Fixed some rare support issues connected with the 1st print layer.
Fixed support issue, where the XY gap was ignored for the top contact layers and a fixed 50% was used instead.
This commit is contained in:
parent
ed2ee2f6f3
commit
688fe3e2b2
2 changed files with 40 additions and 38 deletions
|
@ -131,7 +131,7 @@ void export_print_z_polygons_and_extrusions_to_svg(
|
|||
|
||||
Polygons polygons_support, polygons_interface;
|
||||
support_layer.support_fills.polygons_covered_by_width(polygons_support, SCALED_EPSILON);
|
||||
support_layer.support_interface_fills.polygons_covered_by_width(polygons_interface, SCALED_EPSILON);
|
||||
// support_layer.support_interface_fills.polygons_covered_by_width(polygons_interface, SCALED_EPSILON);
|
||||
svg.draw(union_ex(polygons_support), "brown");
|
||||
svg.draw(union_ex(polygons_interface), "black");
|
||||
|
||||
|
@ -192,6 +192,16 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object
|
|||
external_perimeter_width = std::max(external_perimeter_width, width);
|
||||
}
|
||||
m_gap_xy = m_object_config->support_material_xy_spacing.get_abs_value(external_perimeter_width);
|
||||
|
||||
m_can_merge_support_regions = m_object_config->support_material_extruder.value == m_object_config->support_material_interface_extruder.value;
|
||||
if (! m_can_merge_support_regions && (m_object_config->support_material_extruder.value == 0 || m_object_config->support_material_interface_extruder.value == 0)) {
|
||||
// One of the support extruders is of "don't care" type.
|
||||
auto object_extruders = m_object->print()->object_extruders();
|
||||
if (object_extruders.size() == 1 &&
|
||||
*object_extruders.begin() == std::max(m_object_config->support_material_extruder.value, m_object_config->support_material_interface_extruder.value))
|
||||
// Object is printed with the same extruder as the support.
|
||||
m_can_merge_support_regions = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Using the std::deque as an allocator.
|
||||
|
@ -836,7 +846,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
|||
// on the other side of the object (if it's very thin).
|
||||
{
|
||||
//FIMXE 1) Make the offset configurable, 2) Make the Z span configurable.
|
||||
float slices_margin_offset = float(0.5*fw);
|
||||
float slices_margin_offset = float(scale_(m_gap_xy));
|
||||
if (slices_margin_cached_offset != slices_margin_offset) {
|
||||
slices_margin_cached_offset = slices_margin_offset;
|
||||
slices_margin_cached = offset(lower_layer.slices.expolygons, slices_margin_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
|
@ -913,28 +923,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
|||
new_layer.bottom_z = 0;
|
||||
new_layer.height = m_slicing_params.first_print_layer_height;
|
||||
} else if (this->synchronize_layers()) {
|
||||
// Align bottom of this layer with a top of the closest object layer
|
||||
// while not trespassing into the 1st layer and keeping the support layer thickness bounded.
|
||||
int layer_id_below = int(layer_id) - 1;
|
||||
for (; layer_id_below >= 0; -- layer_id_below) {
|
||||
layer_below = object.layers[layer_id_below];
|
||||
if (layer_below->print_z <= new_layer.print_z - m_support_layer_height_min) {
|
||||
// This is a feasible support layer height.
|
||||
new_layer.bottom_z = layer_below->print_z;
|
||||
new_layer.height = new_layer.print_z - new_layer.bottom_z;
|
||||
assert(new_layer.height <= m_slicing_params.max_suport_layer_height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (layer_id_below == -1) {
|
||||
// Could not align with any of the top surfaces of object layers.
|
||||
if (this->has_raft()) {
|
||||
// If having a raft, all the other layers will be aligned one with the other.
|
||||
} else {
|
||||
// Give up, ignore this layer.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Don't do anything special for the top contact surfaces in regard to synchronizing the layers.
|
||||
// Bottom contact surfaces will be synchronized though.
|
||||
} else {
|
||||
// Don't know the height of the top contact layer yet. The top contact layer is printed with a normal flow and
|
||||
// its height will be set adaptively later on.
|
||||
|
@ -1298,8 +1288,17 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
|
|||
continue;
|
||||
}
|
||||
if (std::abs(extr2z - m_slicing_params.first_print_layer_height) < EPSILON) {
|
||||
// This is a 1st layer supporting some of the early object print layers, its height has been decided in this->top_contact_layers().
|
||||
// This is a bottom of a synchronized (or soluble) top contact layer, its height has been decided in this->top_contact_layers().
|
||||
assert(extr2->layer_type == sltTopContact);
|
||||
assert(extr2->bottom_z == m_slicing_params.first_print_layer_height);
|
||||
assert(extr2->print_z >= m_slicing_params.first_print_layer_height + this->m_support_layer_height_min - EPSILON);
|
||||
if (intermediate_layers.empty() || intermediate_layers.back()->print_z < m_slicing_params.first_print_layer_height) {
|
||||
MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
|
||||
layer_new.bottom_z = 0.;
|
||||
layer_new.print_z = m_slicing_params.first_print_layer_height;
|
||||
layer_new.height = m_slicing_params.first_print_layer_height;
|
||||
intermediate_layers.push_back(&layer_new);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
assert(extr2z >= m_slicing_params.raft_interface_top_z + EPSILON);
|
||||
|
@ -1633,12 +1632,12 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
|
|||
MyLayerStorage &layer_storage) const
|
||||
{
|
||||
// How much to inflate the support columns to be stable. This also applies to the 1st layer, if no raft layers are to be printed.
|
||||
const float inflate_factor_fine = float(scale_(0.5));
|
||||
const float inflate_factor_fine = float(scale_((m_slicing_params.raft_layers() > 1) ? 0.5 : EPSILON));
|
||||
const float inflate_factor_1st_layer = float(scale_(3.)) - inflate_factor_fine;
|
||||
MyLayer *contacts = top_contacts .empty() ? nullptr : top_contacts .front();
|
||||
MyLayer *interfaces = interface_layers.empty() ? nullptr : interface_layers.front();
|
||||
MyLayer *columns_base = base_layers .empty() ? nullptr : base_layers .front();
|
||||
if (contacts != nullptr && contacts->print_z > m_slicing_params.raft_contact_top_z + EPSILON)
|
||||
if (contacts != nullptr && contacts->print_z > std::max(m_slicing_params.first_print_layer_height, m_slicing_params.raft_contact_top_z) + EPSILON)
|
||||
// This is not the raft contact layer.
|
||||
contacts = nullptr;
|
||||
if (interfaces != nullptr && interfaces->bottom_print_z() > m_slicing_params.raft_interface_top_z + EPSILON)
|
||||
|
@ -2181,7 +2180,7 @@ void modulate_extrusion_by_overlapping_layers(
|
|||
// Get the initial extrusion parameters.
|
||||
ExtrusionPath *extrusion_path_template = dynamic_cast<ExtrusionPath*>(extrusions_in_out.front());
|
||||
assert(extrusion_path_template != nullptr);
|
||||
ExtrusionRole extrusion_role = extrusion_path_template->role;
|
||||
ExtrusionRole extrusion_role = extrusion_path_template->role();
|
||||
float extrusion_width = extrusion_path_template->width;
|
||||
|
||||
struct ExtrusionPathFragment
|
||||
|
@ -2491,8 +2490,6 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
|||
assert(support_layer_id < raft_layers.size());
|
||||
SupportLayer &support_layer = *object.support_layers[support_layer_id];
|
||||
assert(support_layer.support_fills.entities.empty());
|
||||
assert(support_layer.support_interface_fills.entities.empty());
|
||||
assert(support_layer.support_islands.expolygons.empty());
|
||||
MyLayer &raft_layer = *raft_layers[support_layer_id];
|
||||
|
||||
std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(ipRectilinear));
|
||||
|
@ -2587,6 +2584,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
|||
std::vector<LayerCacheItem> overlaps;
|
||||
};
|
||||
std::vector<LayerCache> layer_caches(object.support_layers.size(), LayerCache());
|
||||
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, object.support_layers.size()),
|
||||
[this, &object, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &layer_caches, &loop_interface_processor,
|
||||
infill_pattern, &bbox_object, support_density, interface_density, interface_angle, &angles, link_max_length_factor, with_sheath]
|
||||
|
@ -2630,14 +2628,16 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
|||
|
||||
if (m_object_config->support_material_interface_layers == 0) {
|
||||
// If no interface layers were requested, we treat the contact layer exactly as a generic base layer.
|
||||
if (base_layer.could_merge(top_contact_layer))
|
||||
base_layer.merge(std::move(top_contact_layer));
|
||||
else if (base_layer.empty() && !top_contact_layer.empty() && !top_contact_layer.layer->bridging)
|
||||
std::swap(base_layer, top_contact_layer);
|
||||
if (base_layer.could_merge(bottom_contact_layer))
|
||||
base_layer.merge(std::move(bottom_contact_layer));
|
||||
else if (base_layer.empty() && !bottom_contact_layer.empty() && !bottom_contact_layer.layer->bridging)
|
||||
std::swap(base_layer, bottom_contact_layer);
|
||||
if (m_can_merge_support_regions) {
|
||||
if (base_layer.could_merge(top_contact_layer))
|
||||
base_layer.merge(std::move(top_contact_layer));
|
||||
else if (base_layer.empty() && !top_contact_layer.empty() && !top_contact_layer.layer->bridging)
|
||||
std::swap(base_layer, top_contact_layer);
|
||||
if (base_layer.could_merge(bottom_contact_layer))
|
||||
base_layer.merge(std::move(bottom_contact_layer));
|
||||
else if (base_layer.empty() && !bottom_contact_layer.empty() && !bottom_contact_layer.layer->bridging)
|
||||
std::swap(base_layer, bottom_contact_layer);
|
||||
}
|
||||
} else {
|
||||
loop_interface_processor.generate(top_contact_layer, m_support_material_interface_flow);
|
||||
// If no loops are allowed, we treat the contact layer exactly as a generic interface layer.
|
||||
|
|
|
@ -226,6 +226,8 @@ private:
|
|||
Flow m_first_layer_flow;
|
||||
Flow m_support_material_flow;
|
||||
Flow m_support_material_interface_flow;
|
||||
// Is merging of regions allowed? Could the interface & base support regions be printed with the same extruder?
|
||||
bool m_can_merge_support_regions;
|
||||
|
||||
coordf_t m_support_layer_height_min;
|
||||
coordf_t m_support_layer_height_max;
|
||||
|
|
Loading…
Add table
Reference in a new issue