dense_infill (automatic) rework

* better coverage
 * now print in the right sequence
 * fixed overlap (20% of bridge width) with everything for a good grip
supermerill/SuperSlicer#1657
This commit is contained in:
supermerill 2021-10-19 01:49:43 +02:00
parent 240a282625
commit 58c73b1023
4 changed files with 246 additions and 109 deletions

View File

@ -61,6 +61,7 @@ struct SurfaceFillParams : FillParams
RETURN_COMPARE_NON_EQUAL(flow.nozzle_diameter); RETURN_COMPARE_NON_EQUAL(flow.nozzle_diameter);
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, flow.bridge); RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, flow.bridge);
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, role); RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, role);
RETURN_COMPARE_NON_EQUAL_TYPED(int32_t, priority);
return false; return false;
} }
@ -79,7 +80,8 @@ struct SurfaceFillParams : FillParams
this->anchor_length_max == rhs.anchor_length_max&& this->anchor_length_max == rhs.anchor_length_max&&
this->fill_exactly == rhs.fill_exactly && this->fill_exactly == rhs.fill_exactly &&
this->flow == rhs.flow && this->flow == rhs.flow &&
this->role == rhs.role; this->role == rhs.role &&
this->priority == rhs.priority;
} }
}; };
@ -117,6 +119,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
params.density = float(region_config.fill_density) / 100.f; params.density = float(region_config.fill_density) / 100.f;
params.dont_adjust = false; params.dont_adjust = false;
params.connection = region_config.infill_connection.value; params.connection = region_config.infill_connection.value;
params.priority = 0;
if (surface.has_fill_solid()) { if (surface.has_fill_solid()) {
params.density = 1.f; params.density = 1.f;
@ -142,6 +145,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
is_denser = true; is_denser = true;
is_bridge = true; is_bridge = true;
params.pattern = ipRectiWithPerimeter; params.pattern = ipRectiWithPerimeter;
params.priority = surface.priority;
params.connection = InfillConnection::icConnected; params.connection = InfillConnection::icConnected;
} }
if (params.density <= 0 && !is_denser) if (params.density <= 0 && !is_denser)
@ -256,7 +260,9 @@ 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()) { if (fill.params.priority > 0) {
append(all_polygons, to_polygons(fill.expolygons));
}else if (fill.expolygons.size() > 1 || !all_polygons.empty()) {
Polygons polys = to_polygons(std::move(fill.expolygons)); Polygons polys = to_polygons(std::move(fill.expolygons));
// 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<())
@ -390,14 +396,46 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
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();
std::sort(surface_fills.begin(), surface_fills.end(), [](SurfaceFill& s1, SurfaceFill& s2) {
if (s1.region_id == s2.region_id)
return s1.params.priority < s2.params.priority;
return s1.region_id < s2.region_id;
});
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{ {
static int iRun = 0; 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); 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 */ #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
std::vector<ExtrusionEntityCollection*> fills_by_priority;
auto store_fill = [&fills_by_priority, this](size_t region_id) {
if (fills_by_priority.size() == 1) {
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;
ExtrusionEntityCollection* eec = new ExtrusionEntityCollection();
eec->no_sort = true;
m_regions[region_id]->fills.entities.push_back(eec);
for (ExtrusionEntityCollection* per_priority : fills_by_priority) {
if (!per_priority->entities.empty())
eec->entities.push_back(per_priority);
else
delete per_priority;
}
}
fills_by_priority.clear();
};
//surface_fills is sorted by region_id
size_t current_region_id = -1;
for (SurfaceFill &surface_fill : surface_fills) { for (SurfaceFill &surface_fill : surface_fills) {
// store the region fill when changing region.
if (current_region_id != size_t(-1) && current_region_id != surface_fill.region_id) {
store_fill(current_region_id);
}
current_region_id = surface_fill.region_id;
// 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));
f->set_bounding_box(bbox); f->set_bounding_box(bbox);
@ -471,10 +509,14 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
surface_fill.surface.expolygon = std::move(expoly); surface_fill.surface.expolygon = std::move(expoly);
//make fill //make fill
f->fill_surface_extrusion(&surface_fill.surface, surface_fill.params, m_regions[surface_fill.region_id]->fills.entities); while ((size_t)surface_fill.params.priority >= fills_by_priority.size())
fills_by_priority.push_back(new ExtrusionEntityCollection());
f->fill_surface_extrusion(&surface_fill.surface, surface_fill.params, fills_by_priority[(size_t)surface_fill.params.priority]->entities);
} }
} }
} }
if(current_region_id != size_t(-1))
store_fill(current_region_id);
// add thin fill regions // add thin fill regions
// Unpacks the collection, creates multiple collections per path. // Unpacks the collection, creates multiple collections per path.
@ -482,15 +524,35 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
// Why the paths are unpacked? // Why the paths are unpacked?
for (LayerRegion *layerm : m_regions) for (LayerRegion *layerm : m_regions)
for (const ExtrusionEntity *thin_fill : layerm->thin_fills.entities) { for (const ExtrusionEntity *thin_fill : layerm->thin_fills.entities) {
ExtrusionEntityCollection &collection = *(new ExtrusionEntityCollection()); ExtrusionEntityCollection *collection = new ExtrusionEntityCollection();
layerm->fills.entities.push_back(&collection); if (layerm->fills.no_sort && layerm->fills.entities.size() > 0 && layerm->fills.entities[0]->is_collection()) {
collection.entities.push_back(thin_fill->clone()); 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())
static_cast<ExtrusionEntityCollection*>(no_sort_fill->entities[0])->entities.push_back(collection);
} else
layerm->fills.entities.push_back(collection);
collection->entities.push_back(thin_fill->clone());
} }
#ifndef NDEBUG #ifndef NDEBUG
for (LayerRegion *layerm : m_regions) for (LayerRegion *layerm : m_regions)
for (size_t i = 0; i < layerm->fills.entities.size(); ++ i) for (size_t i1 = 0; i1 < layerm->fills.entities.size(); ++i1) {
assert(dynamic_cast<ExtrusionEntityCollection*>(layerm->fills.entities[i]) != nullptr); assert(dynamic_cast<ExtrusionEntityCollection*>(layerm->fills.entities[i1]) != nullptr);
if (layerm->fills.no_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) {
for (size_t i3 = 0; i3 < priority_fill->entities.size(); ++i3)
assert(dynamic_cast<ExtrusionEntityCollection*>(priority_fill->entities[i3]) != nullptr);
}
}
}
}
#endif #endif
} }

View File

@ -71,8 +71,11 @@ struct FillParams
// if role == erNone or ERCustom, this method have to choose the best role itself, else it must use the argument's role. // if role == erNone or ERCustom, this method have to choose the best role itself, else it must use the argument's role.
ExtrusionRole role { erNone }; ExtrusionRole role { erNone };
//flow to use // flow to use
Flow flow = Flow(0.f, 0.f, 0.f, 1.f, false); Flow flow = Flow(0.f, 0.f, 0.f, 1.f, false);
// to order the fills by priority
int32_t priority = 0;
//full configuration for the region, to avoid copying every bit that is needed. Use this for process-specific parameters. //full configuration for the region, to avoid copying every bit that is needed. Use this for process-specific parameters.
PrintRegionConfig const *config{ nullptr }; PrintRegionConfig const *config{ nullptr };

View File

@ -1044,23 +1044,33 @@ namespace Slic3r {
return polygon_reduced; return polygon_reduced;
} }
// find one of the smallest polygon, growing polygon_to_check, only using point into allowedPoints and covering polygon_to_cover. // find one of the smallest polygon, growing polygon_to_cover, only using point into growing_area and covering polygon_to_cover.
ExPolygons dense_fill_fit_to_size(const ExPolygon& polygon_to_cover, const ExPolygons& allowedPoints_todel, ExPolygons dense_fill_fit_to_size(const ExPolygon& bad_polygon_to_cover,
const ExPolygon& growing_area, const coord_t offset, float coverage) { const ExPolygon& growing_area, const coord_t offset, float coverage) {
//fix uncoverable area
ExPolygons polygons_to_cover = intersection_ex(bad_polygon_to_cover, growing_area);
if (polygons_to_cover.size() != 1)
return { bad_polygon_to_cover };
const ExPolygon polygon_to_cover = polygons_to_cover.front();
//grow the polygon_to_check enough to cover polygon_to_cover //grow the polygon_to_check enough to cover polygon_to_cover
float current_coverage = coverage; float current_coverage = coverage;
coord_t previous_offset = 0; coord_t previous_offset = 0;
coord_t current_offset = offset; coord_t current_offset = offset;
//ExPolygon polygon_reduced = try_fit_to_size(polygon_to_cover, allowedPoints);
ExPolygon polygon_reduced = try_fit_to_size2(polygon_to_cover, growing_area); ExPolygon polygon_reduced = try_fit_to_size2(polygon_to_cover, growing_area);
ExPolygon polygon_check; while (polygon_reduced.empty()) {
ExPolygons polygon_checks = offset_ex(intersection(ExPolygons{ polygon_to_cover }, allowedPoints_todel), -SCALED_RESOLUTION); current_offset *= 2;
if (polygon_checks.empty()) ExPolygons bigger_polygon = offset_ex(polygon_to_cover, double(current_offset));
polygon_check = polygon_to_cover; if (bigger_polygon.size() != 1) break;
else bigger_polygon = intersection_ex(bigger_polygon[0], growing_area);
polygon_check = polygon_checks[0]; if (bigger_polygon.size() != 1) break;
while (!diff_ex(polygon_check, polygon_reduced).empty()) { polygon_reduced = try_fit_to_size2(bigger_polygon[0], growing_area);
}
//ExPolygons to_check = offset_ex(polygon_to_cover, -offset);
int idx = 0;
ExPolygons not_covered = diff_ex(polygon_to_cover, polygon_reduced, true);
while (!not_covered.empty()) {
//not enough, use a bigger offset //not enough, use a bigger offset
float percent_coverage = (float)(polygon_reduced.area() / growing_area.area()); float percent_coverage = (float)(polygon_reduced.area() / growing_area.area());
float next_coverage = percent_coverage + (percent_coverage - current_coverage) * 4; float next_coverage = percent_coverage + (percent_coverage - current_coverage) * 4;
@ -1083,6 +1093,7 @@ namespace Slic3r {
} }
//polygon_reduced = try_fit_to_size(bigger_polygon[0], allowedPoints); //polygon_reduced = try_fit_to_size(bigger_polygon[0], allowedPoints);
polygon_reduced = try_fit_to_size2(bigger_polygon[0], growing_area); polygon_reduced = try_fit_to_size2(bigger_polygon[0], growing_area);
not_covered = diff_ex(polygon_to_cover, polygon_reduced, true);
} }
//ok, we have a good one, now try to optimise (unless there are almost no growth) //ok, we have a good one, now try to optimise (unless there are almost no growth)
if (current_offset > offset * 3) { if (current_offset > offset * 3) {
@ -1102,7 +1113,8 @@ namespace Slic3r {
} }
//ExPolygon polygon_test = try_fit_to_size(bigger_polygon[0], allowedPoints); //ExPolygon polygon_test = try_fit_to_size(bigger_polygon[0], allowedPoints);
ExPolygon polygon_test = try_fit_to_size2(bigger_polygon[0], growing_area); ExPolygon polygon_test = try_fit_to_size2(bigger_polygon[0], growing_area);
if (!diff_ex(polygon_to_cover, polygon_test).empty()) { not_covered = diff_ex(polygon_to_cover, polygon_test, true);
if (!not_covered.empty()) {
//bad, not enough, use a bigger offset //bad, not enough, use a bigger offset
previous_offset = new_offset; previous_offset = new_offset;
} else { } else {
@ -1114,7 +1126,16 @@ namespace Slic3r {
} }
//return the area which cover the growing_area. Intersect it to retreive the holes. //return the area which cover the growing_area. Intersect it to retreive the holes.
return intersection_ex(polygon_reduced, growing_area); ExPolygons to_print = intersection_ex(polygon_reduced, growing_area);
//remove polygon not in intersectino with polygon_to_cover
for (int i = 0; i < (int)to_print.size(); i++) {
if (intersection_ex(to_print[i], polygon_to_cover).empty()) {
to_print.erase(to_print.begin() + i);
i--;
}
}
return to_print;
} }
void PrintObject::tag_under_bridge() { void PrintObject::tag_under_bridge() {
@ -1140,99 +1161,140 @@ namespace Slic3r {
previousOne = layerm; previousOne = layerm;
continue; continue;
} }
Surfaces surf_to_add; Surfaces surfs_to_add;
for (Surface& surf : layerm->fill_surfaces.surfaces) { for (Surface& surface : layerm->fill_surfaces.surfaces) {
surf.maxNbSolidLayersOnTop = -1; surface.maxNbSolidLayersOnTop = -1;
if (!surf.has_fill_solid()) { if (!surface.has_fill_solid()) {
Surfaces surf_to_add;
ExPolygons dense_polys; ExPolygons dense_polys;
ExPolygons sparse_polys = { surf.expolygon }; std::vector<uint16_t> dense_priority;
//find the surface which intersect with the smallest maxNb possible ExPolygons surfs_with_overlap = { surface.expolygon };
for (Surface& upp : previousOne->fill_surfaces.surfaces) { ////create a surface with overlap to allow the dense thing to bond to the infill
if (upp.has_fill_solid()) { coord_t scaled_width = layerm->flow(frInfill, true).scaled_width();
// i'm using intersection_ex because the result different than coord_t overlap = scaled_width / 4;
// upp.expolygon.overlaps(surf.expolygon) or surf.expolygon.overlaps(upp.expolygon) for (const ExPolygon& surf_with_overlap : surfs_with_overlap) {
//and a little offset2 to remove the almost supported area ExPolygons sparse_polys = { surf_with_overlap };
ExPolygons intersect = //find the surface which intersect with the smallest maxNb possible
offset2_ex( for (Surface& upp : previousOne->fill_surfaces.surfaces) {
intersection_ex(sparse_polys, { upp.expolygon }, true) if (upp.has_fill_solid()) {
, (float)-layerm->flow(frInfill).scaled_width(), (float)layerm->flow(frInfill).scaled_width()); // i'm using intersection_ex because the result different than
if (!intersect.empty()) { // upp.expolygon.overlaps(surf.expolygon) or surf.expolygon.overlaps(upp.expolygon)
double area_intersect = 0; //and a little offset2 to remove the almost supported area
// calculate area to decide if area is small enough for autofill ExPolygons intersect =
if (layerm->region()->config().infill_dense_algo.value == dfaAutoNotFull || layerm->region()->config().infill_dense_algo.value == dfaAutoOrEnlarged) offset2_ex(
for (ExPolygon poly_inter : intersect) intersection_ex(sparse_polys, { upp.expolygon }, true)
area_intersect += poly_inter.area(); , (float)-layerm->flow(frInfill).scaled_width() / 4, (float)layerm->flow(frInfill).scaled_width() / 4);
if (!intersect.empty()) {
double area_intersect = 0;
// calculate area to decide if area is small enough for autofill
if (layerm->region()->config().infill_dense_algo.value == dfaAutoNotFull || layerm->region()->config().infill_dense_algo.value == dfaAutoOrEnlarged)
for (ExPolygon poly_inter : intersect)
area_intersect += poly_inter.area();
if (layerm->region()->config().infill_dense_algo.value == dfaEnlarged double surf_with_overlap_area = surf_with_overlap.area();
|| (layerm->region()->config().infill_dense_algo.value == dfaAutoOrEnlarged && surf.area() <= area_intersect * COEFF_SPLIT)) { if (layerm->region()->config().infill_dense_algo.value == dfaEnlarged
//expand the area a bit || (layerm->region()->config().infill_dense_algo.value == dfaAutoOrEnlarged && surf_with_overlap_area <= area_intersect * COEFF_SPLIT)) {
intersect = offset_ex(intersect, double(scale_(layerm->region()->config().external_infill_margin.get_abs_value( //expand the area a bit
region->config().perimeters == 0 ? 0 : (layerm->flow(frExternalPerimeter).width + layerm->flow(frPerimeter).spacing() * (region->config().perimeters - 1)))))); intersect = offset_ex(intersect, double(scale_(layerm->region()->config().external_infill_margin.get_abs_value(
} else if (layerm->region()->config().infill_dense_algo.value == dfaAutoNotFull region->config().perimeters == 0 ? 0 : (layerm->flow(frExternalPerimeter).width + layerm->flow(frPerimeter).spacing() * (region->config().perimeters - 1))))));
|| layerm->region()->config().infill_dense_algo.value == dfaAutomatic) { } else if (layerm->region()->config().infill_dense_algo.value == dfaAutoNotFull
|| layerm->region()->config().infill_dense_algo.value == dfaAutomatic) {
//like intersect.empty() but more resilient //like intersect.empty() but more resilient
if (layerm->region()->config().infill_dense_algo.value == dfaAutomatic if (layerm->region()->config().infill_dense_algo.value == dfaAutomatic
|| surf.area() > area_intersect * COEFF_SPLIT) { || surf_with_overlap_area > area_intersect * COEFF_SPLIT) {
ExPolygons cover_intersect; ExPolygons cover_intersect;
// it will be a dense infill, split the surface if needed // it will be a dense infill, split the surface if needed
//ExPolygons cover_intersect; //ExPolygons cover_intersect;
for (ExPolygon& expoly_tocover : intersect) { for (ExPolygon& expoly_tocover : intersect) {
ExPolygons temp = dense_fill_fit_to_size( ExPolygons temp = dense_fill_fit_to_size(
expoly_tocover, expoly_tocover,
diff_ex(offset_ex(layerm->fill_no_overlap_expolygons, double(layerm->flow(frInfill).scaled_width())), offset_ex(layerm->fill_no_overlap_expolygons, double(-layerm->flow(frInfill).scaled_width()))), surf_with_overlap,
surf.expolygon, 4 * layerm->flow(frInfill).scaled_width(),
4 * layerm->flow(frInfill).scaled_width(), 0.01f);
0.01f); cover_intersect.insert(cover_intersect.end(), temp.begin(), temp.end());
cover_intersect.insert(cover_intersect.end(), temp.begin(), temp.end()); }
intersect = cover_intersect;
} else {
intersect.clear();
} }
intersect = cover_intersect; }
} else { if (!intersect.empty()) {
intersect.clear();
ExPolygons sparse_surfaces = diff_ex(sparse_polys, intersect, true);
ExPolygons dense_surfaces = diff_ex(sparse_polys, sparse_surfaces, true);
for (ExPolygon& poly : intersect) {
uint16_t priority = 1;
ExPolygons dense = { poly };
for (size_t idx_dense = 0; idx_dense < dense_polys.size(); idx_dense++) {
ExPolygons dense_test = diff_ex(dense, { dense_polys[idx_dense] }, true);
if (dense_test != dense) {
priority = std::max(priority, uint16_t(dense_priority[idx_dense] + 1));
}
dense = dense_test;
}
dense_polys.insert(dense_polys.end(), dense.begin(), dense.end());
for (int i = 0; i < dense.size(); i++)
dense_priority.push_back(priority);
}
//assign (copy)
sparse_polys = std::move(sparse_surfaces);
} }
} }
if (!intersect.empty()) {
ExPolygons sparse_surfaces = diff_ex(sparse_polys, intersect, true);
ExPolygons dense_surfaces = diff_ex(sparse_polys, sparse_surfaces, true);
//assign (copy)
sparse_polys = std::move(sparse_surfaces);
dense_polys.insert(dense_polys.end(), dense_surfaces.begin(), dense_surfaces.end());
}
} }
//check if we are full-dense
if (sparse_polys.empty()) break;
} }
//check if we are full-dense
if (sparse_polys.empty()) break;
}
//check if we need to split the surface //check if we need to split the surface
if (!dense_polys.empty()) { if (!dense_polys.empty()) {
double area_dense = 0; double area_dense = 0;
for (ExPolygon poly_inter : dense_polys) area_dense += poly_inter.area(); for (ExPolygon poly_inter : dense_polys) area_dense += poly_inter.area();
double area_sparse = 0; double area_sparse = 0;
for (ExPolygon poly_inter : sparse_polys) area_sparse += poly_inter.area(); for (ExPolygon poly_inter : sparse_polys) area_sparse += poly_inter.area();
if (area_sparse > area_dense * 0.1) { // if almost no empty space, simplify by filling everything (else)
//split if (area_sparse > area_dense * 0.1) {
dense_polys = union_ex(dense_polys); //split
for (ExPolygon dense_poly : dense_polys) { //dense_polys = union_ex(dense_polys);
Surface dense_surf(surf, dense_poly); for (int idx_dense = 0; idx_dense < dense_polys.size(); idx_dense++) {
dense_surf.maxNbSolidLayersOnTop = 1; ExPolygon dense_poly = dense_polys[idx_dense];
surf_to_add.push_back(dense_surf); //remove overlap with perimeter
ExPolygons offseted_dense_polys = intersection_ex({ dense_poly }, layerm->fill_no_overlap_expolygons);
//add overlap with everything
offseted_dense_polys = offset_ex(offseted_dense_polys, overlap);
for (ExPolygon offseted_dense_poly : offseted_dense_polys) {
Surface dense_surf(surface, offseted_dense_poly);
dense_surf.maxNbSolidLayersOnTop = 1;
dense_surf.priority = dense_priority[idx_dense];
surf_to_add.push_back(dense_surf);
}
}
sparse_polys = union_ex(sparse_polys);
for (ExPolygon sparse_poly : sparse_polys) {
Surface sparse_surf(surface, sparse_poly);
surf_to_add.push_back(sparse_surf);
}
//layerm->fill_surfaces.surfaces.erase(it_surf);
} else {
surface.maxNbSolidLayersOnTop = 1;
surf_to_add.clear();
surf_to_add.push_back(surface);
break;
} }
sparse_polys = union_ex(sparse_polys);
for (ExPolygon sparse_poly : sparse_polys) {
Surface sparse_surf(surf, sparse_poly);
surf_to_add.push_back(sparse_surf);
}
//layerm->fill_surfaces.surfaces.erase(it_surf);
} else { } else {
surf.maxNbSolidLayersOnTop = 1; surf_to_add.clear();
surf_to_add.push_back(surf); surf_to_add.emplace_back(std::move(surface));
// mitigation: if not possible, don't try the others.
break;
} }
} else surf_to_add.emplace_back(std::move(surf)); }
} else surf_to_add.emplace_back(std::move(surf)); // break go here
surfs_to_add.insert(surfs_to_add.begin(), surf_to_add.begin(), surf_to_add.end());
} else surfs_to_add.emplace_back(std::move(surface));
} }
layerm->fill_surfaces.surfaces = std::move(surf_to_add); layerm->fill_surfaces.surfaces = std::move(surfs_to_add);
previousOne = layerm; previousOne = layerm;
} }
} }

View File

@ -60,42 +60,50 @@ public:
unsigned short thickness_layers; // in layers unsigned short thickness_layers; // in layers
double bridge_angle; // in radians, ccw, 0 = East, only 0+ (negative means undefined) double bridge_angle; // in radians, ccw, 0 = East, only 0+ (negative means undefined)
unsigned short extra_perimeters; unsigned short extra_perimeters;
//for dense infill
uint16_t maxNbSolidLayersOnTop; uint16_t maxNbSolidLayersOnTop;
uint16_t priority;
Surface(const Slic3r::Surface &rhs) Surface(const Slic3r::Surface &rhs)
: surface_type(rhs.surface_type), expolygon(rhs.expolygon), : surface_type(rhs.surface_type), expolygon(rhs.expolygon),
thickness(rhs.thickness), thickness_layers(rhs.thickness_layers), thickness(rhs.thickness), thickness_layers(rhs.thickness_layers),
bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters), bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters),
maxNbSolidLayersOnTop(rhs.maxNbSolidLayersOnTop) maxNbSolidLayersOnTop(rhs.maxNbSolidLayersOnTop),
priority(rhs.priority)
{}; {};
Surface(SurfaceType _surface_type, const ExPolygon &_expolygon) Surface(SurfaceType _surface_type, const ExPolygon &_expolygon)
: surface_type(_surface_type), expolygon(_expolygon), : surface_type(_surface_type), expolygon(_expolygon),
thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0), thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0),
maxNbSolidLayersOnTop(-1) maxNbSolidLayersOnTop(-1),
priority(0)
{}; {};
Surface(const Surface &other, const ExPolygon &_expolygon) Surface(const Surface &other, const ExPolygon &_expolygon)
: surface_type(other.surface_type), expolygon(_expolygon), : surface_type(other.surface_type), expolygon(_expolygon),
thickness(other.thickness), thickness_layers(other.thickness_layers), thickness(other.thickness), thickness_layers(other.thickness_layers),
bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters), bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters),
maxNbSolidLayersOnTop(other.maxNbSolidLayersOnTop) maxNbSolidLayersOnTop(other.maxNbSolidLayersOnTop),
priority(other.priority)
{}; {};
Surface(Surface &&rhs) Surface(Surface &&rhs)
: surface_type(rhs.surface_type), expolygon(std::move(rhs.expolygon)), : surface_type(rhs.surface_type), expolygon(std::move(rhs.expolygon)),
thickness(rhs.thickness), thickness_layers(rhs.thickness_layers), thickness(rhs.thickness), thickness_layers(rhs.thickness_layers),
bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters), bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters),
maxNbSolidLayersOnTop(rhs.maxNbSolidLayersOnTop) maxNbSolidLayersOnTop(rhs.maxNbSolidLayersOnTop),
priority(rhs.priority)
{}; {};
Surface(SurfaceType _surface_type, const ExPolygon &&_expolygon) Surface(SurfaceType _surface_type, const ExPolygon &&_expolygon)
: surface_type(_surface_type), expolygon(std::move(_expolygon)), : surface_type(_surface_type), expolygon(std::move(_expolygon)),
thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0), thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0),
maxNbSolidLayersOnTop(-1) maxNbSolidLayersOnTop(-1),
priority(-1)
{}; {};
Surface(const Surface &other, const ExPolygon &&_expolygon) Surface(const Surface &other, const ExPolygon &&_expolygon)
: surface_type(other.surface_type), expolygon(std::move(_expolygon)), : surface_type(other.surface_type), expolygon(std::move(_expolygon)),
thickness(other.thickness), thickness_layers(other.thickness_layers), thickness(other.thickness), thickness_layers(other.thickness_layers),
bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters), bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters),
maxNbSolidLayersOnTop(other.maxNbSolidLayersOnTop) maxNbSolidLayersOnTop(other.maxNbSolidLayersOnTop),
priority(other.priority)
{}; {};
Surface& operator=(const Surface &rhs) Surface& operator=(const Surface &rhs)
@ -107,6 +115,7 @@ public:
bridge_angle = rhs.bridge_angle; bridge_angle = rhs.bridge_angle;
extra_perimeters = rhs.extra_perimeters; extra_perimeters = rhs.extra_perimeters;
maxNbSolidLayersOnTop = rhs.maxNbSolidLayersOnTop; maxNbSolidLayersOnTop = rhs.maxNbSolidLayersOnTop;
priority = rhs.priority;
return *this; return *this;
} }
@ -119,6 +128,7 @@ public:
bridge_angle = rhs.bridge_angle; bridge_angle = rhs.bridge_angle;
extra_perimeters = rhs.extra_perimeters; extra_perimeters = rhs.extra_perimeters;
maxNbSolidLayersOnTop = rhs.maxNbSolidLayersOnTop; maxNbSolidLayersOnTop = rhs.maxNbSolidLayersOnTop;
priority = rhs.priority;
return *this; return *this;
} }