Fixing missing dense raft layers with number of support top interface
layers set to zero. Fixes #7951, second picture.
This commit is contained in:
parent
2098ce9cfa
commit
8354d2b52c
@ -335,6 +335,7 @@ SupportParameters::SupportParameters(const PrintObject &object)
|
|||||||
this->first_layer_flow = Slic3r::support_material_1st_layer_flow(&object, float(slicing_params.first_print_layer_height));
|
this->first_layer_flow = Slic3r::support_material_1st_layer_flow(&object, float(slicing_params.first_print_layer_height));
|
||||||
this->support_material_flow = Slic3r::support_material_flow(&object, float(slicing_params.layer_height));
|
this->support_material_flow = Slic3r::support_material_flow(&object, float(slicing_params.layer_height));
|
||||||
this->support_material_interface_flow = Slic3r::support_material_interface_flow(&object, float(slicing_params.layer_height));
|
this->support_material_interface_flow = Slic3r::support_material_interface_flow(&object, float(slicing_params.layer_height));
|
||||||
|
this->raft_interface_flow = support_material_interface_flow;
|
||||||
|
|
||||||
// Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um.
|
// Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um.
|
||||||
this->support_layer_height_min = scaled<coord_t>(0.01);
|
this->support_layer_height_min = scaled<coord_t>(0.01);
|
||||||
@ -377,13 +378,14 @@ SupportParameters::SupportParameters(const PrintObject &object)
|
|||||||
|
|
||||||
this->base_angle = Geometry::deg2rad(float(object_config.support_material_angle.value));
|
this->base_angle = Geometry::deg2rad(float(object_config.support_material_angle.value));
|
||||||
this->interface_angle = Geometry::deg2rad(float(object_config.support_material_angle.value + 90.));
|
this->interface_angle = Geometry::deg2rad(float(object_config.support_material_angle.value + 90.));
|
||||||
this->interface_spacing = object_config.support_material_interface_spacing.value + this->support_material_interface_flow.spacing();
|
double interface_spacing = object_config.support_material_interface_spacing.value + this->support_material_interface_flow.spacing();
|
||||||
this->interface_density = std::min(1., this->support_material_interface_flow.spacing() / this->interface_spacing);
|
this->interface_density = std::min(1., this->support_material_interface_flow.spacing() / interface_spacing);
|
||||||
this->support_spacing = object_config.support_material_spacing.value + this->support_material_flow.spacing();
|
double raft_interface_spacing = object_config.support_material_interface_spacing.value + this->raft_interface_flow.spacing();
|
||||||
this->support_density = std::min(1., this->support_material_flow.spacing() / this->support_spacing);
|
this->raft_interface_density = std::min(1., this->raft_interface_flow.spacing() / raft_interface_spacing);
|
||||||
|
double support_spacing = object_config.support_material_spacing.value + this->support_material_flow.spacing();
|
||||||
|
this->support_density = std::min(1., this->support_material_flow.spacing() / support_spacing);
|
||||||
if (object_config.support_material_interface_layers.value == 0) {
|
if (object_config.support_material_interface_layers.value == 0) {
|
||||||
// No interface layers allowed, print everything with the base support pattern.
|
// No interface layers allowed, print everything with the base support pattern.
|
||||||
this->interface_spacing = this->support_spacing;
|
|
||||||
this->interface_density = this->support_density;
|
this->interface_density = this->support_density;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +395,7 @@ SupportParameters::SupportParameters(const PrintObject &object)
|
|||||||
support_pattern == smpHoneycomb ? ipHoneycomb :
|
support_pattern == smpHoneycomb ? ipHoneycomb :
|
||||||
this->support_density > 0.95 || this->with_sheath ? ipRectilinear : ipSupportBase;
|
this->support_density > 0.95 || this->with_sheath ? ipRectilinear : ipSupportBase;
|
||||||
this->interface_fill_pattern = (this->interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
this->interface_fill_pattern = (this->interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
||||||
|
this->raft_interface_fill_pattern = this->raft_interface_density > 0.95 ? ipRectilinear : ipSupportBase;
|
||||||
this->contact_fill_pattern =
|
this->contact_fill_pattern =
|
||||||
(object_config.support_material_interface_pattern == smipAuto && slicing_params.soluble_interface) ||
|
(object_config.support_material_interface_pattern == smipAuto && slicing_params.soluble_interface) ||
|
||||||
object_config.support_material_interface_pattern == smipConcentric ?
|
object_config.support_material_interface_pattern == smipConcentric ?
|
||||||
@ -4240,11 +4243,11 @@ void generate_support_toolpaths(
|
|||||||
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
|
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
|
||||||
{
|
{
|
||||||
assert(support_layer_id < raft_layers.size());
|
assert(support_layer_id < raft_layers.size());
|
||||||
SupportLayer &support_layer = *support_layers[support_layer_id];
|
SupportLayer &support_layer = *support_layers[support_layer_id];
|
||||||
assert(support_layer.support_fills.entities.empty());
|
assert(support_layer.support_fills.entities.empty());
|
||||||
SupportGeneratorLayer &raft_layer = *raft_layers[support_layer_id];
|
SupportGeneratorLayer &raft_layer = *raft_layers[support_layer_id];
|
||||||
|
|
||||||
std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(support_params.interface_fill_pattern));
|
std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(support_params.raft_interface_fill_pattern));
|
||||||
std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(support_params.base_fill_pattern));
|
std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(support_params.base_fill_pattern));
|
||||||
filler_interface->set_bounding_box(bbox_object);
|
filler_interface->set_bounding_box(bbox_object);
|
||||||
filler_support->set_bounding_box(bbox_object);
|
filler_support->set_bounding_box(bbox_object);
|
||||||
@ -4299,8 +4302,8 @@ void generate_support_toolpaths(
|
|||||||
// value that guarantees that all layers are correctly aligned.
|
// value that guarantees that all layers are correctly aligned.
|
||||||
filler->spacing = support_params.support_material_flow.spacing();
|
filler->spacing = support_params.support_material_flow.spacing();
|
||||||
assert(! raft_layer.bridging);
|
assert(! raft_layer.bridging);
|
||||||
flow = Flow(float(support_params.support_material_interface_flow.width()), float(raft_layer.height), support_params.support_material_flow.nozzle_diameter());
|
flow = Flow(float(support_params.raft_interface_flow.width()), float(raft_layer.height), support_params.raft_interface_flow.nozzle_diameter());
|
||||||
density = float(support_params.interface_density);
|
density = float(support_params.raft_interface_density);
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density));
|
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density));
|
||||||
@ -4343,7 +4346,7 @@ void generate_support_toolpaths(
|
|||||||
|
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, support_layers.size()),
|
tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, support_layers.size()),
|
||||||
[&config, &support_params, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor,
|
[&config, &support_params, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor,
|
||||||
&bbox_object, &angles, link_max_length_factor]
|
&bbox_object, &angles, n_raft_layers, link_max_length_factor]
|
||||||
(const tbb::blocked_range<size_t>& range) {
|
(const tbb::blocked_range<size_t>& range) {
|
||||||
// Indices of the 1st layer in their respective container at the support layer height.
|
// Indices of the 1st layer in their respective container at the support layer height.
|
||||||
size_t idx_layer_bottom_contact = size_t(-1);
|
size_t idx_layer_bottom_contact = size_t(-1);
|
||||||
@ -4357,6 +4360,11 @@ void generate_support_toolpaths(
|
|||||||
auto filler_first_layer_ptr = std::unique_ptr<Fill>(range.begin() == 0 && support_params.contact_fill_pattern != fill_type_first_layer ? Fill::new_from_type(fill_type_first_layer) : nullptr);
|
auto filler_first_layer_ptr = std::unique_ptr<Fill>(range.begin() == 0 && support_params.contact_fill_pattern != fill_type_first_layer ? Fill::new_from_type(fill_type_first_layer) : nullptr);
|
||||||
// Pointer to the 1st layer interface filler.
|
// Pointer to the 1st layer interface filler.
|
||||||
auto filler_first_layer = filler_first_layer_ptr ? filler_first_layer_ptr.get() : filler_interface.get();
|
auto filler_first_layer = filler_first_layer_ptr ? filler_first_layer_ptr.get() : filler_interface.get();
|
||||||
|
// Filler for the 1st layer interface, if different from filler_interface.
|
||||||
|
auto filler_raft_contact_ptr = std::unique_ptr<Fill>(range.begin() == n_raft_layers && config.support_material_interface_layers.value == 0 ?
|
||||||
|
Fill::new_from_type(support_params.raft_interface_fill_pattern) : nullptr);
|
||||||
|
// Pointer to the 1st layer interface filler.
|
||||||
|
auto filler_raft_contact = filler_raft_contact_ptr ? filler_raft_contact_ptr.get() : filler_interface.get();
|
||||||
// Filler for the base interface (to be used for soluble interface / non soluble base, to produce non soluble interface layer below soluble interface layer).
|
// Filler for the base interface (to be used for soluble interface / non soluble base, to produce non soluble interface layer below soluble interface layer).
|
||||||
auto filler_base_interface = std::unique_ptr<Fill>(base_interface_layers.empty() ? nullptr :
|
auto filler_base_interface = std::unique_ptr<Fill>(base_interface_layers.empty() ? nullptr :
|
||||||
Fill::new_from_type(support_params.interface_density > 0.95 || support_params.with_sheath ? ipRectilinear : ipSupportBase));
|
Fill::new_from_type(support_params.interface_density > 0.95 || support_params.with_sheath ? ipRectilinear : ipSupportBase));
|
||||||
@ -4364,6 +4372,8 @@ void generate_support_toolpaths(
|
|||||||
filler_interface->set_bounding_box(bbox_object);
|
filler_interface->set_bounding_box(bbox_object);
|
||||||
if (filler_first_layer_ptr)
|
if (filler_first_layer_ptr)
|
||||||
filler_first_layer_ptr->set_bounding_box(bbox_object);
|
filler_first_layer_ptr->set_bounding_box(bbox_object);
|
||||||
|
if (filler_raft_contact_ptr)
|
||||||
|
filler_raft_contact_ptr->set_bounding_box(bbox_object);
|
||||||
if (filler_base_interface)
|
if (filler_base_interface)
|
||||||
filler_base_interface->set_bounding_box(bbox_object);
|
filler_base_interface->set_bounding_box(bbox_object);
|
||||||
filler_support->set_bounding_box(bbox_object);
|
filler_support->set_bounding_box(bbox_object);
|
||||||
@ -4402,10 +4412,12 @@ void generate_support_toolpaths(
|
|||||||
if (idx_layer_intermediate < intermediate_layers.size() && intermediate_layers[idx_layer_intermediate]->print_z < support_layer.print_z + EPSILON)
|
if (idx_layer_intermediate < intermediate_layers.size() && intermediate_layers[idx_layer_intermediate]->print_z < support_layer.print_z + EPSILON)
|
||||||
base_layer.layer = intermediate_layers[idx_layer_intermediate];
|
base_layer.layer = intermediate_layers[idx_layer_intermediate];
|
||||||
|
|
||||||
|
bool raft_layer = support_layer_id == n_raft_layers;
|
||||||
if (config.support_material_interface_layers == 0) {
|
if (config.support_material_interface_layers == 0) {
|
||||||
// If no top interface layers were requested, we treat the contact layer exactly as a generic base layer.
|
// If no top interface layers were requested, we treat the contact layer exactly as a generic base layer.
|
||||||
if (support_params.can_merge_support_regions) {
|
// Don't merge the raft contact layer though.
|
||||||
if (base_layer.could_merge(top_contact_layer))
|
if (support_params.can_merge_support_regions && ! raft_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())
|
else if (base_layer.empty())
|
||||||
base_layer = std::move(top_contact_layer);
|
base_layer = std::move(top_contact_layer);
|
||||||
@ -4415,7 +4427,7 @@ void generate_support_toolpaths(
|
|||||||
// 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.
|
||||||
// Merge interface_layer into top_contact_layer, as the top_contact_layer is not synchronized and therefore it will be used
|
// Merge interface_layer into top_contact_layer, as the top_contact_layer is not synchronized and therefore it will be used
|
||||||
// to trim other layers.
|
// to trim other layers.
|
||||||
if (top_contact_layer.could_merge(interface_layer))
|
if (top_contact_layer.could_merge(interface_layer) && ! raft_layer)
|
||||||
top_contact_layer.merge(std::move(interface_layer));
|
top_contact_layer.merge(std::move(interface_layer));
|
||||||
}
|
}
|
||||||
if ((config.support_material_interface_layers == 0 || config.support_material_bottom_interface_layers == 0) && support_params.can_merge_support_regions) {
|
if ((config.support_material_interface_layers == 0 || config.support_material_bottom_interface_layers == 0) && support_params.can_merge_support_regions) {
|
||||||
@ -4423,7 +4435,7 @@ void generate_support_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)
|
||||||
base_layer = std::move(bottom_contact_layer);
|
base_layer = std::move(bottom_contact_layer);
|
||||||
} else if (bottom_contact_layer.could_merge(top_contact_layer))
|
} else if (bottom_contact_layer.could_merge(top_contact_layer) && ! raft_layer)
|
||||||
top_contact_layer.merge(std::move(bottom_contact_layer));
|
top_contact_layer.merge(std::move(bottom_contact_layer));
|
||||||
else if (bottom_contact_layer.could_merge(interface_layer))
|
else if (bottom_contact_layer.could_merge(interface_layer))
|
||||||
bottom_contact_layer.merge(std::move(interface_layer));
|
bottom_contact_layer.merge(std::move(interface_layer));
|
||||||
@ -4441,35 +4453,44 @@ void generate_support_toolpaths(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Top and bottom contacts, interface layers.
|
// Top and bottom contacts, interface layers.
|
||||||
for (size_t i = 0; i < 3; ++ i) {
|
enum class InterfaceLayerType { TopContact, BottomContact, RaftContact, Interface, InterfaceAsBase };
|
||||||
SupportGeneratorLayerExtruded &layer_ex = (i == 0) ? top_contact_layer : (i == 1 ? bottom_contact_layer : interface_layer);
|
auto extrude_interface = [&](SupportGeneratorLayerExtruded &layer_ex, InterfaceLayerType interface_layer_type) {
|
||||||
if (layer_ex.empty() || layer_ex.polygons_to_extrude().empty())
|
if (! layer_ex.empty() && ! layer_ex.polygons_to_extrude().empty()) {
|
||||||
continue;
|
bool interface_as_base = interface_layer_type == InterfaceLayerType::InterfaceAsBase;
|
||||||
bool interface_as_base = config.support_material_interface_layers.value == 0 ||
|
bool raft_contact = interface_layer_type == InterfaceLayerType::RaftContact;
|
||||||
(config.support_material_bottom_interface_layers == 0 && &layer_ex == &bottom_contact_layer);
|
//FIXME Bottom interfaces are extruded with the briding flow. Some bridging layers have its height slightly reduced, therefore
|
||||||
//FIXME Bottom interfaces are extruded with the briding flow. Some bridging layers have its height slightly reduced, therefore
|
// the bridging flow does not quite apply. Reduce the flow to area of an ellipse? (A = pi * a * b)
|
||||||
// the bridging flow does not quite apply. Reduce the flow to area of an ellipse? (A = pi * a * b)
|
auto *filler = raft_contact ? filler_raft_contact : filler_interface.get();
|
||||||
auto interface_flow = layer_ex.layer->bridging ?
|
auto interface_flow = layer_ex.layer->bridging ?
|
||||||
Flow::bridging_flow(layer_ex.layer->height, support_params.support_material_bottom_interface_flow.nozzle_diameter()) :
|
Flow::bridging_flow(layer_ex.layer->height, support_params.support_material_bottom_interface_flow.nozzle_diameter()) :
|
||||||
(interface_as_base ? &support_params.support_material_flow : &support_params.support_material_interface_flow)->with_height(float(layer_ex.layer->height));
|
(raft_contact ? &support_params.raft_interface_flow :
|
||||||
filler_interface->angle = interface_as_base ?
|
interface_as_base ? &support_params.support_material_flow : &support_params.support_material_interface_flow)
|
||||||
// If zero interface layers are configured, use the same angle as for the base layers.
|
->with_height(float(layer_ex.layer->height));
|
||||||
angles[support_layer_id % angles.size()] :
|
filler->angle = interface_as_base ?
|
||||||
// Use interface angle for the interface layers.
|
// If zero interface layers are configured, use the same angle as for the base layers.
|
||||||
support_params.interface_angle + interface_angle_delta;
|
angles[support_layer_id % angles.size()] :
|
||||||
double density = interface_as_base ? support_params.support_density : support_params.interface_density;
|
// Use interface angle for the interface layers.
|
||||||
filler_interface->spacing = interface_as_base ? support_params.support_material_flow.spacing() : support_params.support_material_interface_flow.spacing();
|
support_params.interface_angle + interface_angle_delta;
|
||||||
filler_interface->link_max_length = coord_t(scale_(filler_interface->spacing * link_max_length_factor / density));
|
double density = raft_contact ? support_params.raft_interface_density : interface_as_base ? support_params.support_density : support_params.interface_density;
|
||||||
fill_expolygons_generate_paths(
|
filler->spacing = raft_contact ? support_params.raft_interface_flow.spacing() :
|
||||||
// Destination
|
interface_as_base ? support_params.support_material_flow.spacing() : support_params.support_material_interface_flow.spacing();
|
||||||
layer_ex.extrusions,
|
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density));
|
||||||
// Regions to fill
|
fill_expolygons_generate_paths(
|
||||||
union_safety_offset_ex(layer_ex.polygons_to_extrude()),
|
// Destination
|
||||||
// Filler and its parameters
|
layer_ex.extrusions,
|
||||||
filler_interface.get(), float(density),
|
// Regions to fill
|
||||||
// Extrusion parameters
|
union_safety_offset_ex(layer_ex.polygons_to_extrude()),
|
||||||
ExtrusionRole::SupportMaterialInterface, interface_flow);
|
// Filler and its parameters
|
||||||
}
|
filler, float(density),
|
||||||
|
// Extrusion parameters
|
||||||
|
ExtrusionRole::SupportMaterialInterface, interface_flow);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const bool top_interfaces = config.support_material_interface_layers.value != 0;
|
||||||
|
const bool bottom_interfaces = top_interfaces && config.support_material_bottom_interface_layers != 0;
|
||||||
|
extrude_interface(top_contact_layer, raft_layer ? InterfaceLayerType::RaftContact : top_interfaces ? InterfaceLayerType::TopContact : InterfaceLayerType::InterfaceAsBase);
|
||||||
|
extrude_interface(bottom_contact_layer, bottom_interfaces ? InterfaceLayerType::BottomContact : InterfaceLayerType::InterfaceAsBase);
|
||||||
|
extrude_interface(interface_layer, top_interfaces ? InterfaceLayerType::Interface : InterfaceLayerType::InterfaceAsBase);
|
||||||
|
|
||||||
// Base interface layers under soluble interfaces
|
// Base interface layers under soluble interfaces
|
||||||
if ( ! base_interface_layer.empty() && ! base_interface_layer.polygons_to_extrude().empty()) {
|
if ( ! base_interface_layer.empty() && ! base_interface_layer.polygons_to_extrude().empty()) {
|
||||||
|
@ -122,10 +122,17 @@ using SupportGeneratorLayersPtr = std::vector<SupportGeneratorLayer*>;
|
|||||||
struct SupportParameters {
|
struct SupportParameters {
|
||||||
SupportParameters(const PrintObject &object);
|
SupportParameters(const PrintObject &object);
|
||||||
|
|
||||||
|
// Flow at the 1st print layer.
|
||||||
Flow first_layer_flow;
|
Flow first_layer_flow;
|
||||||
|
// Flow at the support base (neither top, nor bottom interface).
|
||||||
|
// Also flow at the raft base with the exception of raft interface and contact layers.
|
||||||
Flow support_material_flow;
|
Flow support_material_flow;
|
||||||
|
// Flow at the top interface and contact layers.
|
||||||
Flow support_material_interface_flow;
|
Flow support_material_interface_flow;
|
||||||
|
// Flow at the bottom interfaces and contacts.
|
||||||
Flow support_material_bottom_interface_flow;
|
Flow support_material_bottom_interface_flow;
|
||||||
|
// Flow at raft inteface & contact layers.
|
||||||
|
Flow raft_interface_flow;
|
||||||
// Is merging of regions allowed? Could the interface & base support regions be printed with the same extruder?
|
// Is merging of regions allowed? Could the interface & base support regions be printed with the same extruder?
|
||||||
bool can_merge_support_regions;
|
bool can_merge_support_regions;
|
||||||
|
|
||||||
@ -136,14 +143,23 @@ struct SupportParameters {
|
|||||||
|
|
||||||
float base_angle;
|
float base_angle;
|
||||||
float interface_angle;
|
float interface_angle;
|
||||||
coordf_t interface_spacing;
|
|
||||||
|
// Density of the top / bottom interface and contact layers.
|
||||||
coordf_t interface_density;
|
coordf_t interface_density;
|
||||||
coordf_t support_spacing;
|
// Density of the raft interface and contact layers.
|
||||||
|
coordf_t raft_interface_density;
|
||||||
|
// Density of the base support layers.
|
||||||
coordf_t support_density;
|
coordf_t support_density;
|
||||||
|
|
||||||
|
// Pattern of the sparse infill including sparse raft layers.
|
||||||
InfillPattern base_fill_pattern;
|
InfillPattern base_fill_pattern;
|
||||||
|
// Pattern of the top / bottom interface and contact layers.
|
||||||
InfillPattern interface_fill_pattern;
|
InfillPattern interface_fill_pattern;
|
||||||
|
// Pattern of the raft interface and contact layers.
|
||||||
|
InfillPattern raft_interface_fill_pattern;
|
||||||
|
// Pattern of the contact layers.
|
||||||
InfillPattern contact_fill_pattern;
|
InfillPattern contact_fill_pattern;
|
||||||
|
// Shall the sparse (base) layers be printed with a single perimeter line (sheath) for robustness?
|
||||||
bool with_sheath;
|
bool with_sheath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user