mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
FIX: adaptive layer height may mess up support layers
We must ensure when independent support layer height is enabled, the
support layers are strictly synced with object layers. Otherwise, the
wipe tower toolchange may be messed up.
Jira: STUDIO-4097
Change-Id: I6208653f9665b15d028940d5e130c9e895629fc2
(cherry picked from commit 41d35c8af152c91cb356a68d88a879a115b44778)
(cherry picked from commit 2b593ce378
)
This commit is contained in:
parent
5f450923c9
commit
e8d4291e02
1 changed files with 71 additions and 13 deletions
|
@ -1685,6 +1685,48 @@ static inline std::tuple<Polygons, Polygons, double> detect_contacts(
|
|||
return std::make_tuple(std::move(contact_polygons), std::move(enforcer_polygons), no_interface_offset);
|
||||
}
|
||||
|
||||
// find the object layer that is closest to the {layer.bottom_z-gap_support_object} for top contact,
|
||||
// or {layer.print_z+gap_object_support} for bottom contact
|
||||
Layer* sync_gap_with_object_layer(const Layer& layer, const coordf_t gap_support_object, bool is_top_contact)
|
||||
{
|
||||
// sync gap with the object layer height
|
||||
float gap_synced = 0;
|
||||
if (is_top_contact) {
|
||||
Layer* lower_layer = layer.lower_layer, * last_valid_gap_layer = layer.lower_layer;
|
||||
while (lower_layer && gap_synced < gap_support_object) {
|
||||
last_valid_gap_layer = lower_layer;
|
||||
gap_synced += lower_layer->height;
|
||||
lower_layer = lower_layer->lower_layer;
|
||||
|
||||
}
|
||||
// maybe gap_synced is too large, find the nearest object layer (one layer above may be better)
|
||||
if (std::abs(gap_synced - last_valid_gap_layer->height - gap_support_object) < std::abs(gap_synced - gap_support_object)) {
|
||||
gap_synced -= last_valid_gap_layer->height;
|
||||
last_valid_gap_layer = last_valid_gap_layer->upper_layer;
|
||||
}
|
||||
lower_layer = last_valid_gap_layer; // layer just below the last valid gap layer
|
||||
if (last_valid_gap_layer->lower_layer)
|
||||
lower_layer = last_valid_gap_layer->lower_layer;
|
||||
return lower_layer;
|
||||
}else{
|
||||
Layer* upper_layer = layer.upper_layer, * last_valid_gap_layer = layer.upper_layer;
|
||||
while (upper_layer && gap_synced < gap_support_object) {
|
||||
last_valid_gap_layer = upper_layer;
|
||||
gap_synced += upper_layer->height;
|
||||
upper_layer = upper_layer->upper_layer;
|
||||
}
|
||||
// maybe gap_synced is too large, find the nearest object layer (one layer above may be better)
|
||||
if (std::abs(gap_synced - last_valid_gap_layer->height - gap_support_object) < std::abs(gap_synced - gap_support_object)) {
|
||||
gap_synced -= last_valid_gap_layer->height;
|
||||
last_valid_gap_layer = last_valid_gap_layer->lower_layer;
|
||||
}
|
||||
upper_layer = last_valid_gap_layer; // layer just above the last valid gap layer
|
||||
if (last_valid_gap_layer->upper_layer)
|
||||
upper_layer = last_valid_gap_layer->upper_layer;
|
||||
return upper_layer;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate one, possibly two support contact layers.
|
||||
// For "thick" overhangs, one support layer will be generated to support normal extrusions, the other to support the "thick" extrusions.
|
||||
static inline std::pair<SupportGeneratorLayer*, SupportGeneratorLayer*> new_contact_layer(
|
||||
|
@ -1712,9 +1754,18 @@ static inline std::pair<SupportGeneratorLayer*, SupportGeneratorLayer*> new_cont
|
|||
print_z = layer.bottom_z();
|
||||
height = layer.lower_layer->height;
|
||||
bottom_z = (layer_id == 1) ? slicing_params.object_print_z_min : layer.lower_layer->lower_layer->print_z;
|
||||
} else {
|
||||
print_z = layer.bottom_z() - slicing_params.gap_support_object;
|
||||
height = print_config.independent_support_layer_height ? 0. : layer.lower_layer->height/*object_config.layer_height*/; // BBS: need to consider adaptive layer heights
|
||||
}
|
||||
else {
|
||||
// BBS: need to consider adaptive layer heights
|
||||
if (print_config.independent_support_layer_height) {
|
||||
print_z = layer.bottom_z() - slicing_params.gap_support_object;
|
||||
height = 0;
|
||||
}
|
||||
else {
|
||||
Layer* synced_layer = sync_gap_with_object_layer(layer, slicing_params.gap_support_object, true);
|
||||
print_z = synced_layer->print_z;
|
||||
height = synced_layer->height;
|
||||
}
|
||||
bottom_z = print_z - height;
|
||||
// Ignore this contact area if it's too low.
|
||||
// Don't want to print a layer below the first layer height as it may not stick well.
|
||||
|
@ -1739,7 +1790,7 @@ static inline std::pair<SupportGeneratorLayer*, SupportGeneratorLayer*> new_cont
|
|||
|
||||
// Contact layer will be printed with a normal flow, but
|
||||
// it will support layers printed with a bridging flow.
|
||||
if (object_config.thick_bridges && SupportMaterialInternal::has_bridging_extrusions(layer)) {
|
||||
if (object_config.thick_bridges && SupportMaterialInternal::has_bridging_extrusions(layer) && print_config.independent_support_layer_height) {
|
||||
coordf_t bridging_height = 0.;
|
||||
for (const LayerRegion* region : layer.regions())
|
||||
bridging_height += region->region().bridging_height_avg(print_config);
|
||||
|
@ -2373,15 +2424,22 @@ static inline SupportGeneratorLayer* detect_bottom_contacts(
|
|||
// Grow top surfaces so that interface and support generation are generated
|
||||
// with some spacing from object - it looks we don't need the actual
|
||||
// top shapes so this can be done here
|
||||
//FIXME calculate layer height based on the actual thickness of the layer:
|
||||
// If the layer is extruded with no bridging flow, support just the normal extrusions.
|
||||
layer_new.height = slicing_params.soluble_interface || !object.print()->config().independent_support_layer_height ?
|
||||
// Align the interface layer with the object's layer height.
|
||||
layer.upper_layer->height :
|
||||
// Place a bridge flow interface layer or the normal flow interface layer over the top surface.
|
||||
support_params.support_material_bottom_interface_flow.height();
|
||||
layer_new.print_z = slicing_params.soluble_interface ? layer.upper_layer->print_z :
|
||||
layer.print_z + layer_new.height + slicing_params.gap_object_support;
|
||||
if (object.print()->config().independent_support_layer_height) {
|
||||
// If the layer is extruded with no bridging flow, support just the normal extrusions.
|
||||
layer_new.height = slicing_params.soluble_interface?
|
||||
// Align the interface layer with the object's layer height.
|
||||
layer.upper_layer->height :
|
||||
// Place a bridge flow interface layer or the normal flow interface layer over the top surface.
|
||||
support_params.support_material_bottom_interface_flow.height();
|
||||
layer_new.print_z = slicing_params.soluble_interface ? layer.upper_layer->print_z :
|
||||
layer.print_z + layer_new.height + slicing_params.gap_object_support;
|
||||
}
|
||||
else {
|
||||
Layer* synced_layer = sync_gap_with_object_layer(layer, slicing_params.gap_object_support, false);
|
||||
// If the layer is extruded with no bridging flow, support just the normal extrusions.
|
||||
layer_new.height = synced_layer->height;
|
||||
layer_new.print_z = synced_layer->print_z;
|
||||
}
|
||||
layer_new.bottom_z = layer.print_z;
|
||||
layer_new.idx_object_layer_below = layer_id;
|
||||
layer_new.bridging = !slicing_params.soluble_interface && object.config().thick_bridges;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue