mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 00:05:59 +08:00
optimize the brdige over infill by extractng only the sparse infill lines from previous layer
This commit is contained in:
parent
feb9310fe3
commit
e4910381b4
@ -643,6 +643,94 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Polylines Layer::generate_sparse_infill_polylines_for_anchoring() const
|
||||||
|
{
|
||||||
|
std::vector<SurfaceFill> surface_fills = group_fills(*this);
|
||||||
|
const Slic3r::BoundingBox bbox = this->object()->bounding_box();
|
||||||
|
const auto resolution = this->object()->print()->config().gcode_resolution.value;
|
||||||
|
|
||||||
|
Polylines sparse_infill_polylines{};
|
||||||
|
|
||||||
|
for (SurfaceFill &surface_fill : surface_fills) {
|
||||||
|
// skip patterns for which additional input is nullptr
|
||||||
|
switch (surface_fill.params.pattern) {
|
||||||
|
case ipLightning: continue; break;
|
||||||
|
case ipAdaptiveCubic: continue; break;
|
||||||
|
case ipSupportCubic: continue; break;
|
||||||
|
case ipCount: continue; break;
|
||||||
|
case ipSupportBase: continue; break;
|
||||||
|
case ipEnsuring: continue; break;
|
||||||
|
case ipRectilinear:
|
||||||
|
case ipMonotonic:
|
||||||
|
case ipMonotonicLines:
|
||||||
|
case ipAlignedRectilinear:
|
||||||
|
case ipGrid:
|
||||||
|
case ipTriangles:
|
||||||
|
case ipStars:
|
||||||
|
case ipCubic:
|
||||||
|
case ipLine:
|
||||||
|
case ipConcentric:
|
||||||
|
case ipHoneycomb:
|
||||||
|
case ip3DHoneycomb:
|
||||||
|
case ipGyroid:
|
||||||
|
case ipHilbertCurve:
|
||||||
|
case ipArchimedeanChords:
|
||||||
|
case ipOctagramSpiral: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the filler object.
|
||||||
|
std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));
|
||||||
|
f->set_bounding_box(bbox);
|
||||||
|
f->layer_id = this->id();
|
||||||
|
f->z = this->print_z;
|
||||||
|
f->angle = surface_fill.params.angle;
|
||||||
|
// f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
|
||||||
|
f->print_config = &this->object()->print()->config();
|
||||||
|
f->print_object_config = &this->object()->config();
|
||||||
|
|
||||||
|
// calculate flow spacing for infill pattern generation
|
||||||
|
double link_max_length = 0.;
|
||||||
|
if (!surface_fill.params.bridge) {
|
||||||
|
#if 0
|
||||||
|
link_max_length = layerm.region()->config().get_abs_value(surface.is_external() ? "external_fill_link_max_length" : "fill_link_max_length", flow.spacing());
|
||||||
|
// printf("flow spacing: %f, is_external: %d, link_max_length: %lf\n", flow.spacing(), int(surface.is_external()), link_max_length);
|
||||||
|
#else
|
||||||
|
if (surface_fill.params.density > 80.) // 80%
|
||||||
|
link_max_length = 3. * f->spacing;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maximum length of the perimeter segment linking two infill lines.
|
||||||
|
f->link_max_length = (coord_t) scale_(link_max_length);
|
||||||
|
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
||||||
|
f->loop_clipping = coord_t(scale_(surface_fill.params.flow.nozzle_diameter()) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER);
|
||||||
|
|
||||||
|
LayerRegion &layerm = *m_regions[surface_fill.region_id];
|
||||||
|
|
||||||
|
// apply half spacing using this flow's own spacing and generate infill
|
||||||
|
FillParams params;
|
||||||
|
params.density = float(0.01 * surface_fill.params.density);
|
||||||
|
params.dont_adjust = false; // surface_fill.params.dont_adjust;
|
||||||
|
params.anchor_length = surface_fill.params.anchor_length;
|
||||||
|
params.anchor_length_max = surface_fill.params.anchor_length_max;
|
||||||
|
params.resolution = resolution;
|
||||||
|
params.use_arachne = false;
|
||||||
|
params.layer_height = layerm.layer()->height;
|
||||||
|
|
||||||
|
for (ExPolygon &expoly : surface_fill.expolygons) {
|
||||||
|
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
||||||
|
f->spacing = surface_fill.params.spacing;
|
||||||
|
surface_fill.surface.expolygon = std::move(expoly);
|
||||||
|
try {
|
||||||
|
Polylines polylines = f->fill_surface(&surface_fill.surface, params);
|
||||||
|
sparse_infill_polylines.insert(sparse_infill_polylines.end(), polylines.begin(), polylines.end());
|
||||||
|
} catch (InfillFailedException &) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sparse_infill_polylines;
|
||||||
|
}
|
||||||
|
|
||||||
// Create ironing extrusions over top surfaces.
|
// Create ironing extrusions over top surfaces.
|
||||||
void Layer::make_ironing()
|
void Layer::make_ironing()
|
||||||
{
|
{
|
||||||
|
@ -369,6 +369,7 @@ public:
|
|||||||
// Phony version of make_fills() without parameters for Perl integration only.
|
// Phony version of make_fills() without parameters for Perl integration only.
|
||||||
void make_fills() { this->make_fills(nullptr, nullptr, nullptr); }
|
void make_fills() { this->make_fills(nullptr, nullptr, nullptr); }
|
||||||
void make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree, FillLightning::Generator* lightning_generator);
|
void make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree, FillLightning::Generator* lightning_generator);
|
||||||
|
Polylines generate_sparse_infill_polylines_for_anchoring() const;
|
||||||
void make_ironing();
|
void make_ironing();
|
||||||
|
|
||||||
void export_region_slices_to_svg(const char *path) const;
|
void export_region_slices_to_svg(const char *path) const;
|
||||||
|
@ -397,6 +397,7 @@ void PrintObject::infill()
|
|||||||
this->prepare_infill();
|
this->prepare_infill();
|
||||||
|
|
||||||
if (this->set_started(posInfill)) {
|
if (this->set_started(posInfill)) {
|
||||||
|
m_print->set_status(45, L("making infill"));
|
||||||
auto [adaptive_fill_octree, support_fill_octree] = this->prepare_adaptive_infill_data();
|
auto [adaptive_fill_octree, support_fill_octree] = this->prepare_adaptive_infill_data();
|
||||||
auto lightning_generator = this->prepare_lightning_infill_data();
|
auto lightning_generator = this->prepare_lightning_infill_data();
|
||||||
|
|
||||||
@ -1658,18 +1659,8 @@ void PrintObject::bridge_over_infill()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, temporarily fill the previous layer and extract the extrusions.
|
// generate sparse infill polylines from lower layers to get anchorable polylines
|
||||||
// TODO - the make_fills function does a lot of work, some of it is not needed (e.g. sorting the paths)
|
Polylines lower_layer_polylines = po->get_layer(lidx)->lower_layer->generate_sparse_infill_polylines_for_anchoring();
|
||||||
// It would be nice to have a function that only creates the fill polylines, ideally without modifying the global state
|
|
||||||
po->get_layer(lidx)->lower_layer->make_fills(nullptr, nullptr, nullptr);
|
|
||||||
Polylines lower_layer_polylines;
|
|
||||||
for (const LayerRegion *region : layer->lower_layer->m_regions) {
|
|
||||||
for (const ExtrusionEntity *ee : region->fills().entities) {
|
|
||||||
assert(ee->is_collection());
|
|
||||||
auto region_polylines = dynamic_cast<const ExtrusionEntityCollection *>(ee)->as_polylines();
|
|
||||||
lower_layer_polylines.insert(lower_layer_polylines.end(), region_polylines.begin(), region_polylines.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::pair<const LayerSlice *, SurfacesPtr> candidates : bridging_surface_candidates) {
|
for (std::pair<const LayerSlice *, SurfacesPtr> candidates : bridging_surface_candidates) {
|
||||||
if (candidates.second.empty()) {
|
if (candidates.second.empty()) {
|
||||||
@ -1786,7 +1777,7 @@ void PrintObject::bridge_over_infill()
|
|||||||
assert(candidate->surface_type == stInternalSolid);
|
assert(candidate->surface_type == stInternalSolid);
|
||||||
Polygons bridged_area = expand(to_polygons(candidate->expolygon), flow.scaled_spacing());
|
Polygons bridged_area = expand(to_polygons(candidate->expolygon), flow.scaled_spacing());
|
||||||
Polygons infill_region = to_polygons(surface_to_region[candidate]->fill_expolygons());
|
Polygons infill_region = to_polygons(surface_to_region[candidate]->fill_expolygons());
|
||||||
bool touches_perimeter = !diff(bridged_area, infill_region).empty();
|
bool touches_perimeter = !diff(bridged_area, infill_region).empty();
|
||||||
bool touches_solid_region_under = !intersection(bridged_area, not_sparse_infill).empty();
|
bool touches_solid_region_under = !intersection(bridged_area, not_sparse_infill).empty();
|
||||||
|
|
||||||
bridged_area =
|
bridged_area =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user