Skip to content

Commit

Permalink
Merge branch 'stable'
Browse files Browse the repository at this point in the history
  • Loading branch information
supermerill committed Dec 11, 2021
2 parents eaa52a4 + b1e0448 commit 0d84565
Show file tree
Hide file tree
Showing 25 changed files with 421 additions and 161 deletions.
1 change: 1 addition & 0 deletions resources/ui_layout/print.ui
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ group:Layer height
setting:first_layer_height
group:Filtering
setting:resolution
setting:resolution_internal
setting:model_precision
setting:slice_closing_radius
group:Modifying slices
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/ClipperUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType
co.ArcTolerance = miterLimit;
else
co.MiterLimit = miterLimit;
double delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
double delta_scaled = delta * double(CLIPPER_OFFSET_SCALE);
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
co.AddPaths(input, joinType, endType);
ClipperLib::Paths retval;
Expand Down
16 changes: 10 additions & 6 deletions src/libslic3r/ExtrusionEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,21 +213,25 @@ void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang)
this->split_at_vertex(p);
}

void ExtrusionLoop::clip_end(double distance, ExtrusionPaths* paths) const
ExtrusionPaths clip_end(ExtrusionPaths& paths, double distance)
{
*paths = this->paths;
ExtrusionPaths removed;

while (distance > 0 && !paths->empty()) {
ExtrusionPath &last = paths->back();
while (distance > 0 && !paths.empty()) {
ExtrusionPath& last = paths.back();
removed.push_back(last);
double len = last.length();
if (len <= distance) {
paths->pop_back();
paths.pop_back();
distance -= len;
} else {
last.polyline.clip_end(distance);
removed.back().polyline.clip_start(removed.back().polyline.length() - distance);
break;
}
}
std::reverse(removed.begin(), removed.end());
return removed;
}

bool ExtrusionLoop::has_overhang_point(const Point &point) const
Expand Down Expand Up @@ -376,7 +380,7 @@ void ExtrusionPrinter::use(const ExtrusionEntityCollection &collection) {
if (i != 0) ss << ",";
collection.entities[i]->visit(*this);
}
if(collection.no_sort) ss<<", no_sort=true";
if(!collection.can_sort()) ss<<", no_sort=true";
ss << "}";
}

Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/ExtrusionEntity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ class ExtrusionPath : public ExtrusionEntity
ExtrusionRole m_role;
};
typedef std::vector<ExtrusionPath> ExtrusionPaths;
ExtrusionPaths clip_end(ExtrusionPaths& paths, double distance);

class ExtrusionPath3D : public ExtrusionPath {
public:
Expand Down Expand Up @@ -451,7 +452,6 @@ class ExtrusionLoop : public ExtrusionEntity
double length() const override;
bool split_at_vertex(const Point &point);
void split_at(const Point &point, bool prefer_non_overhang);
void clip_end(double distance, ExtrusionPaths* paths) const;
// 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;
Expand Down
4 changes: 2 additions & 2 deletions src/libslic3r/ExtrusionEntityCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void ExtrusionEntityCollection::reverse()
{
// Don't reverse it if it's a loop, as it doesn't change anything in terms of elements ordering
// and caller might rely on winding order
if (!ptr->can_reverse())
if (ptr->can_reverse() && !ptr->is_loop())
ptr->reverse();
}
std::reverse(this->entities.begin(), this->entities.end());
Expand Down Expand Up @@ -151,7 +151,7 @@ ExtrusionEntityCollection ExtrusionEntityCollection::flatten(bool preserve_order
}
void
FlatenEntities::use(const ExtrusionEntityCollection &coll) {
if ((coll.no_sort || this->to_fill.no_sort) && preserve_ordering) {
if ((!coll.can_sort() || !this->to_fill.can_sort()) && preserve_ordering) {
FlatenEntities unsortable(coll, preserve_ordering);
for (const ExtrusionEntity* entity : coll.entities) {
entity->visit(unsortable);
Expand Down
20 changes: 13 additions & 7 deletions src/libslic3r/ExtrusionEntityCollection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ inline ExtrusionEntitiesPtr filter_by_extrusion_role(const ExtrusionEntitiesPtr

class ExtrusionEntityCollection : public ExtrusionEntity
{
private:
// set to tru to forbit to reorder and reverse all entities indie us.
bool no_sort;
// even if no_sort, allow to reverse() us (and our entities if they allow it, but they should)
bool no_reverse;
public:
virtual ExtrusionEntityCollection* clone() const override { return new ExtrusionEntityCollection(*this); }
// Create a new object, initialize it with this object using the move semantics.
Expand All @@ -33,14 +38,13 @@ class ExtrusionEntityCollection : public ExtrusionEntity
/// Owned ExtrusionEntities and descendent ExtrusionEntityCollections.
/// Iterating over this needs to check each child to see if it, too is a collection.
ExtrusionEntitiesPtr entities; // we own these entities
bool no_sort;
ExtrusionEntityCollection(): no_sort(false) {}
ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort) { this->append(other.entities); }
ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort) {}
ExtrusionEntityCollection(): no_sort(false), no_reverse(false) {}
ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort), no_reverse(other.no_reverse) { this->append(other.entities); }
ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort), no_reverse(other.no_reverse) {}
explicit ExtrusionEntityCollection(const ExtrusionPaths &paths);
ExtrusionEntityCollection& operator=(const ExtrusionEntityCollection &other);
ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other)
{ this->entities = std::move(other.entities); this->no_sort = other.no_sort; return *this; }
{ this->entities = std::move(other.entities); this->no_sort = other.no_sort; this->no_reverse = other.no_reverse; return *this; }
~ExtrusionEntityCollection() { clear(); }

/// Operator to convert and flatten this collection to a single vector of ExtrusionPaths.
Expand All @@ -55,7 +59,9 @@ class ExtrusionEntityCollection : public ExtrusionEntity
}
return out;
}
bool can_reverse() const override { return !this->no_sort; }
void set_can_sort_reverse(bool sort, bool reverse) { this->no_sort = !sort; this->no_reverse = !reverse; }
bool can_sort() const { return !this->no_sort; }
bool can_reverse() const override { return can_sort() || !this->no_reverse; }
bool empty() const { return this->entities.empty(); }
void clear();
void swap (ExtrusionEntityCollection &c);
Expand Down Expand Up @@ -152,7 +158,7 @@ class FlatenEntities : public ExtrusionVisitorConst {
public:
FlatenEntities(bool preserve_ordering) : preserve_ordering(preserve_ordering) {}
FlatenEntities(ExtrusionEntityCollection pattern, bool preserve_ordering) : preserve_ordering(preserve_ordering) {
to_fill.no_sort = pattern.no_sort;
to_fill.set_can_sort_reverse(pattern.can_sort(), pattern.can_reverse());
}
ExtrusionEntityCollection get() {
return to_fill;
Expand Down
24 changes: 13 additions & 11 deletions src/libslic3r/Fill/Fill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,9 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
m_regions[region_id]->fills.append(fills_by_priority[0]->entities);
delete fills_by_priority[0];
} else {
m_regions[region_id]->fills.no_sort = true;
m_regions[region_id]->fills.set_can_sort_reverse(false, false);
ExtrusionEntityCollection* eec = new ExtrusionEntityCollection();
eec->no_sort = true;
eec->set_can_sort_reverse(false, false);
m_regions[region_id]->fills.entities.push_back(eec);
for (ExtrusionEntityCollection* per_priority : fills_by_priority) {
if (!per_priority->entities.empty())
Expand Down Expand Up @@ -486,6 +486,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
surface_fill.params.flow = Flow::new_from_spacing((float)f->get_spacing(), surface_fill.params.flow.nozzle_diameter, (float)surface_fill.params.flow.height, overlap, surface_fill.params.flow.bridge);
}

//union with safety offset to avoid separation from the appends of different surface with same settings.
surface_fill.expolygons = union_ex(surface_fill.expolygons, true);

for (ExPolygon &expoly : surface_fill.expolygons) {
//set overlap polygons
Expand All @@ -508,17 +510,15 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:

//adjust the bridge density
if (surface_fill.params.flow.bridge && surface_fill.params.density > 0.99 /*&& layerm->region()->config().bridge_overlap.get_abs_value(1) != 1*/) {
////varies the overlap to have teh best coverage for the bridge
////varies the overlap to have the best coverage for the bridge
//surface_fill.params.density *= float(layerm->region()->config().bridge_overlap.get_abs_value(1));
double min_spacing = 0.999 * surface_fill.params.spacing / surface_fill.params.config->bridge_overlap.get_abs_value(surface_fill.params.density);
double max_spacing = 1.001 * surface_fill.params.spacing / surface_fill.params.config->bridge_overlap_min.get_abs_value(surface_fill.params.density);
double factor = 1.00001;
if (min_spacing < max_spacing * 1.01) {
// create a bouding box of the rotated surface
coord_t bounding_box_size_x = 0;
Polygon poly = surface_fill.surface.expolygon.contour;
coord_t bounding_box_min_x = 0;
poly.rotate(PI / 2 - (surface_fill.params.bridge_angle < 0 ? surface_fill.params.angle : surface_fill.params.bridge_angle));
ExPolygons expolys;
if (surface_fill.params.bridge_angle > 0 && !f->no_overlap_expolygons.empty()) {
//take only the no-overlap area
Expand All @@ -530,7 +530,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
bool first = true;
for (ExPolygon& expoly : expolys) {
expoly.holes.clear();
expoly.rotate(PI / 2 - (surface_fill.params.bridge_angle < 0 ? surface_fill.params.angle : surface_fill.params.bridge_angle));
expoly.rotate(PI / 2 + (surface_fill.params.bridge_angle < 0 ? surface_fill.params.angle : surface_fill.params.bridge_angle));
if (first) {
bb = expoly.contour.bounding_box();
first = false;
Expand Down Expand Up @@ -558,6 +558,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
surface_fill.params.density = surface_fill.params.config->bridge_overlap.get_abs_value(surface_fill.params.density);
}
}
Polygon poly = surface_fill.surface.expolygon.contour;
poly.rotate(PI / 2 + (surface_fill.params.bridge_angle < 0 ? surface_fill.params.angle : surface_fill.params.bridge_angle));
surface_fill.params.dont_adjust = true;
surface_fill.params.bridge_offset = std::abs(poly.bounding_box().min.x() - bounding_box_min_x);
}
Expand All @@ -580,9 +582,9 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
for (LayerRegion *layerm : m_regions)
for (const ExtrusionEntity *thin_fill : layerm->thin_fills.entities) {
ExtrusionEntityCollection *collection = new ExtrusionEntityCollection();
if (layerm->fills.no_sort && layerm->fills.entities.size() > 0 && layerm->fills.entities[0]->is_collection()) {
if (!layerm->fills.can_sort() && layerm->fills.entities.size() > 0 && layerm->fills.entities[0]->is_collection()) {
ExtrusionEntityCollection* no_sort_fill = static_cast<ExtrusionEntityCollection*>(layerm->fills.entities[0]);
if (no_sort_fill->no_sort && no_sort_fill->entities.size() > 0 && no_sort_fill->entities[0]->is_collection())
if (!no_sort_fill->can_sort() && no_sort_fill->entities.size() > 0 && no_sort_fill->entities[0]->is_collection())
static_cast<ExtrusionEntityCollection*>(no_sort_fill->entities[0])->entities.push_back(collection);
} else
layerm->fills.entities.push_back(collection);
Expand All @@ -593,15 +595,15 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
for (LayerRegion *layerm : m_regions)
for (size_t i1 = 0; i1 < layerm->fills.entities.size(); ++i1) {
assert(dynamic_cast<ExtrusionEntityCollection*>(layerm->fills.entities[i1]) != nullptr);
if (layerm->fills.no_sort && layerm->fills.entities.size() > 0 && i1 == 0){
if (!layerm->fills.can_sort() && layerm->fills.entities.size() > 0 && i1 == 0){
ExtrusionEntityCollection* no_sort_fill = static_cast<ExtrusionEntityCollection*>(layerm->fills.entities[0]);
assert(no_sort_fill != nullptr);
assert(!no_sort_fill->empty());
for (size_t i2 = 0; i2 < no_sort_fill->entities.size(); ++i2) {
ExtrusionEntityCollection* priority_fill = dynamic_cast<ExtrusionEntityCollection*>(no_sort_fill->entities[i2]);
assert(priority_fill != nullptr);
assert(!priority_fill->empty());
if (no_sort_fill->no_sort) {
if (!no_sort_fill->can_sort()) {
for (size_t i3 = 0; i3 < priority_fill->entities.size(); ++i3)
assert(dynamic_cast<ExtrusionEntityCollection*>(priority_fill->entities[i3]) != nullptr);
}
Expand Down Expand Up @@ -780,7 +782,7 @@ void Layer::make_ironing()
ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
ironing_params.layerm->ironings.entities.push_back(eec);
// Don't sort the ironing infill lines as they are monotonicly ordered.
eec->no_sort = true;
eec->set_can_sort_reverse(false, false);
extrusion_entities_append_paths(
eec->entities, std::move(polylines),
erIroning,
Expand Down
6 changes: 3 additions & 3 deletions src/libslic3r/Fill/FillBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &para
// Save into layer.
auto *eec = new ExtrusionEntityCollection();
/// pass the no_sort attribute to the extrusion path
eec->no_sort = this->no_sort();
eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
/// add it into the collection
out.push_back(eec);
//get the role
Expand Down Expand Up @@ -269,7 +269,7 @@ Fill::do_gap_fill(const ExPolygons& gapfill_areas, const FillParams& params, Ext
}
#endif

ExtrusionEntityCollection gap_fill = thin_variable_width(polylines_gapfill, erGapFill, params.flow);
ExtrusionEntityCollection gap_fill = thin_variable_width(polylines_gapfill, erGapFill, params.flow, scale_t(params.config->get_computed_value("resolution_internal")));
//set role if needed
/*if (params.role != erSolidInfill) {
ExtrusionSetRole set_good_role(params.role);
Expand All @@ -278,7 +278,7 @@ Fill::do_gap_fill(const ExPolygons& gapfill_areas, const FillParams& params, Ext
//move them into the collection
if (!gap_fill.entities.empty()) {
ExtrusionEntityCollection* coll_gapfill = new ExtrusionEntityCollection();
coll_gapfill->no_sort = this->no_sort();
coll_gapfill->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
coll_gapfill->append(std::move(gap_fill.entities));
coll_out.push_back(coll_gapfill);
}
Expand Down
4 changes: 2 additions & 2 deletions src/libslic3r/Fill/FillConcentric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ FillConcentricWGapFill::fill_surface_extrusion(
ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);

ExtrusionEntityCollection *coll_nosort = new ExtrusionEntityCollection();
coll_nosort->no_sort = true; //can be sorted inside the pass
coll_nosort->set_can_sort_reverse(false, false); //can be sorted inside the pass
extrusion_entities_append_loops(
coll_nosort->entities, loops,
good_role,
Expand All @@ -154,7 +154,7 @@ FillConcentricWGapFill::fill_surface_extrusion(
}
}
if (!polylines.empty() && !is_bridge(good_role)) {
ExtrusionEntityCollection gap_fill = thin_variable_width(polylines, erGapFill, params.flow);
ExtrusionEntityCollection gap_fill = thin_variable_width(polylines, erGapFill, params.flow, scale_t(params.config->get_computed_value("resolution_internal")));
//set role if needed
if (good_role != erSolidInfill) {
ExtrusionSetRole set_good_role(good_role);
Expand Down
24 changes: 14 additions & 10 deletions src/libslic3r/Fill/FillGyroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,8 @@ static std::vector<Vec2d> make_one_period(double width, double scaleFactor, doub
return points;
}

static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double line_spacing, double width, double height)
static Polylines make_gyroid_waves(coordf_t gridZ, coordf_t scaleFactor, double width, double height, double tolerance)
{
const double scaleFactor = scale_(line_spacing) / density_adjusted;

// tolerance in scaled units. clamp the maximum tolerance as there's
// no processing-speed benefit to do so beyond a certain point
const double tolerance = std::min(line_spacing / 2, FillGyroid::PatternTolerance) / unscale<double>(scaleFactor);

//scale factor for 5% : 8 712 388
// 1z = 10^-6 mm ?
Expand Down Expand Up @@ -167,13 +162,22 @@ void FillGyroid::_fill_surface_single(
// align bounding box to a multiple of our grid module
bb.merge(_align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance)));

// tolerance in scaled units. clamp the maximum tolerance as there's
// no processing-speed benefit to do so beyond a certain point
const coordf_t scaleFactor = scale_d(this->get_spacing()) / density_adjusted;
const double tolerance_old = std::min(this->get_spacing() / 2, FillGyroid::PatternTolerance) / unscaled(scaleFactor);
const double tolerance_old2 = std::min(this->get_spacing() / 2, FillGyroid::PatternTolerance) * density_adjusted / this->get_spacing();
const double tolerance = params.config->get_computed_value("resolution_internal") * density_adjusted / this->get_spacing();
std::cout << "gyroid tolerance: " << tolerance_old << " == " << tolerance_old2 << " ? "<< tolerance << "\n";
std::cout << "this->get_spacing(): " << this->get_spacing() << " , scaleFactor= " << unscaled(scaleFactor) << " , min(spa, 0.2)= " << std::min(this->get_spacing() / 2, FillGyroid::PatternTolerance) << "\n";

// generate pattern
Polylines polylines = make_gyroid_waves(
(double)scale_(this->z),
density_adjusted,
this->get_spacing(),
scale_d(this->z),
scaleFactor,
ceil(bb.size()(0) / distance) + 1.,
ceil(bb.size()(1) / distance) + 1.);
ceil(bb.size()(1) / distance) + 1.,
tolerance);

// shift the polyline to the grid origin
for (Polyline &pl : polylines)
Expand Down
Loading

0 comments on commit 0d84565

Please sign in to comment.