mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-14 02:07:54 -06:00
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;
|
Polygons polygons_support, polygons_interface;
|
||||||
support_layer.support_fills.polygons_covered_by_width(polygons_support, SCALED_EPSILON);
|
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_support), "brown");
|
||||||
svg.draw(union_ex(polygons_interface), "black");
|
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);
|
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_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.
|
// 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).
|
// on the other side of the object (if it's very thin).
|
||||||
{
|
{
|
||||||
//FIMXE 1) Make the offset configurable, 2) Make the Z span configurable.
|
//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) {
|
if (slices_margin_cached_offset != slices_margin_offset) {
|
||||||
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);
|
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.bottom_z = 0;
|
||||||
new_layer.height = m_slicing_params.first_print_layer_height;
|
new_layer.height = m_slicing_params.first_print_layer_height;
|
||||||
} else if (this->synchronize_layers()) {
|
} else if (this->synchronize_layers()) {
|
||||||
// Align bottom of this layer with a top of the closest object layer
|
// Don't do anything special for the top contact surfaces in regard to synchronizing the layers.
|
||||||
// while not trespassing into the 1st layer and keeping the support layer thickness bounded.
|
// Bottom contact surfaces will be synchronized though.
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Don't know the height of the top contact layer yet. The top contact layer is printed with a normal flow and
|
// 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.
|
// its height will be set adaptively later on.
|
||||||
|
@ -1298,8 +1288,17 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (std::abs(extr2z - m_slicing_params.first_print_layer_height) < EPSILON) {
|
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->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;
|
continue;
|
||||||
}
|
}
|
||||||
assert(extr2z >= m_slicing_params.raft_interface_top_z + EPSILON);
|
assert(extr2z >= m_slicing_params.raft_interface_top_z + EPSILON);
|
||||||
|
@ -1633,12 +1632,12 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
|
||||||
MyLayerStorage &layer_storage) const
|
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.
|
// 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;
|
const float inflate_factor_1st_layer = float(scale_(3.)) - inflate_factor_fine;
|
||||||
MyLayer *contacts = top_contacts .empty() ? nullptr : top_contacts .front();
|
MyLayer *contacts = top_contacts .empty() ? nullptr : top_contacts .front();
|
||||||
MyLayer *interfaces = interface_layers.empty() ? nullptr : interface_layers.front();
|
MyLayer *interfaces = interface_layers.empty() ? nullptr : interface_layers.front();
|
||||||
MyLayer *columns_base = base_layers .empty() ? nullptr : base_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.
|
// This is not the raft contact layer.
|
||||||
contacts = nullptr;
|
contacts = nullptr;
|
||||||
if (interfaces != nullptr && interfaces->bottom_print_z() > m_slicing_params.raft_interface_top_z + EPSILON)
|
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.
|
// Get the initial extrusion parameters.
|
||||||
ExtrusionPath *extrusion_path_template = dynamic_cast<ExtrusionPath*>(extrusions_in_out.front());
|
ExtrusionPath *extrusion_path_template = dynamic_cast<ExtrusionPath*>(extrusions_in_out.front());
|
||||||
assert(extrusion_path_template != nullptr);
|
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;
|
float extrusion_width = extrusion_path_template->width;
|
||||||
|
|
||||||
struct ExtrusionPathFragment
|
struct ExtrusionPathFragment
|
||||||
|
@ -2491,8 +2490,6 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||||
assert(support_layer_id < raft_layers.size());
|
assert(support_layer_id < raft_layers.size());
|
||||||
SupportLayer &support_layer = *object.support_layers[support_layer_id];
|
SupportLayer &support_layer = *object.support_layers[support_layer_id];
|
||||||
assert(support_layer.support_fills.entities.empty());
|
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];
|
MyLayer &raft_layer = *raft_layers[support_layer_id];
|
||||||
|
|
||||||
std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(ipRectilinear));
|
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<LayerCacheItem> overlaps;
|
||||||
};
|
};
|
||||||
std::vector<LayerCache> layer_caches(object.support_layers.size(), LayerCache());
|
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()),
|
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,
|
[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]
|
infill_pattern, &bbox_object, support_density, interface_density, interface_angle, &angles, link_max_length_factor, with_sheath]
|
||||||
|
@ -2630,6 +2628,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||||
|
|
||||||
if (m_object_config->support_material_interface_layers == 0) {
|
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 no interface layers were requested, we treat the contact layer exactly as a generic base layer.
|
||||||
|
if (m_can_merge_support_regions) {
|
||||||
if (base_layer.could_merge(top_contact_layer))
|
if (base_layer.could_merge(top_contact_layer))
|
||||||
base_layer.merge(std::move(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)
|
else if (base_layer.empty() && !top_contact_layer.empty() && !top_contact_layer.layer->bridging)
|
||||||
|
@ -2638,6 +2637,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||||
base_layer.merge(std::move(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)
|
else if (base_layer.empty() && !bottom_contact_layer.empty() && !bottom_contact_layer.layer->bridging)
|
||||||
std::swap(base_layer, bottom_contact_layer);
|
std::swap(base_layer, bottom_contact_layer);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
loop_interface_processor.generate(top_contact_layer, m_support_material_interface_flow);
|
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.
|
// 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_first_layer_flow;
|
||||||
Flow m_support_material_flow;
|
Flow m_support_material_flow;
|
||||||
Flow m_support_material_interface_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_min;
|
||||||
coordf_t m_support_layer_height_max;
|
coordf_t m_support_layer_height_max;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue