Also check void volume before bridging over infill. #3468 #1986

This commit is contained in:
Alessandro Ranellucci 2016-12-19 17:04:34 +01:00
parent 807b0111ed
commit 4724f0fb99

View File

@ -526,13 +526,13 @@ void
PrintObject::bridge_over_infill() PrintObject::bridge_over_infill()
{ {
FOREACH_REGION(this->_print, region) { FOREACH_REGION(this->_print, region) {
size_t region_id = region - this->_print->regions.begin(); const size_t region_id = region - this->_print->regions.begin();
// skip bridging in case there are no voids // skip bridging in case there are no voids
if ((*region)->config.fill_density.value == 100) continue; if ((*region)->config.fill_density.value == 100) continue;
// get bridge flow // get bridge flow
Flow bridge_flow = (*region)->flow( const Flow bridge_flow = (*region)->flow(
frSolidInfill, frSolidInfill,
-1, // layer height, not relevant for bridge flow -1, // layer height, not relevant for bridge flow
true, // bridge true, // bridge
@ -541,6 +541,9 @@ PrintObject::bridge_over_infill()
*this *this
); );
// get the average extrusion volume per surface unit
const double mm3_per_mm2 = bridge_flow.mm3_per_mm() / bridge_flow.width;
FOREACH_LAYER(this, layer_it) { FOREACH_LAYER(this, layer_it) {
// skip first layer // skip first layer
if (layer_it == this->layers.begin()) continue; if (layer_it == this->layers.begin()) continue;
@ -559,13 +562,23 @@ PrintObject::bridge_over_infill()
{ {
Polygons to_bridge_pp = internal_solid; Polygons to_bridge_pp = internal_solid;
// Only bridge where internal infill exists below the solid shell matching
// these two conditions:
// 1) its depth is at least equal to our bridge extrusion diameter;
// 2) its free volume (thus considering infill density) is at least equal
// to the volume needed by our bridge flow.
double excess_mm3_per_mm2 = mm3_per_mm2;
// iterate through lower layers spanned by bridge_flow // iterate through lower layers spanned by bridge_flow
double bottom_z = layer->print_z - bridge_flow.height; const double bottom_z = layer->print_z - bridge_flow.height;
for (int i = (layer_it - this->layers.begin()) - 1; i >= 0; --i) { for (int i = (layer_it - this->layers.begin()) - 1; i >= 0; --i) {
const Layer* lower_layer = this->layers[i]; const Layer* lower_layer = this->layers[i];
// stop iterating if layer is lower than bottom_z // subtract the void volume of this layer
if (lower_layer->print_z < bottom_z) break; excess_mm3_per_mm2 -= lower_layer->height * (100 - (*region)->config.fill_density.value)/100;
// stop iterating if both conditions are matched
if (lower_layer->print_z < bottom_z && excess_mm3_per_mm2 <= 0) break;
// iterate through regions and collect internal surfaces // iterate through regions and collect internal surfaces
Polygons lower_internal; Polygons lower_internal;
@ -576,9 +589,12 @@ PrintObject::bridge_over_infill()
to_bridge_pp = intersection(to_bridge_pp, lower_internal); to_bridge_pp = intersection(to_bridge_pp, lower_internal);
} }
// don't bridge if the volume condition isn't matched
if (excess_mm3_per_mm2 > 0) continue;
// there's no point in bridging too thin/short regions // there's no point in bridging too thin/short regions
{ {
double min_width = bridge_flow.scaled_width() * 3; const double min_width = bridge_flow.scaled_width() * 3;
to_bridge_pp = offset2(to_bridge_pp, -min_width, +min_width); to_bridge_pp = offset2(to_bridge_pp, -min_width, +min_width);
} }
@ -593,7 +609,7 @@ PrintObject::bridge_over_infill()
#endif #endif
// compute the remaning internal solid surfaces as difference // compute the remaning internal solid surfaces as difference
ExPolygons not_to_bridge = diff_ex(internal_solid, to_polygons(to_bridge), true); const ExPolygons not_to_bridge = diff_ex(internal_solid, to_polygons(to_bridge), true);
// build the new collection of fill_surfaces // build the new collection of fill_surfaces
{ {