WIP: Splitting the number of top / bottom support interface layers.
If the new support_material_bottom_interface_layers is left at default -1, then support_material_interface_layers is used for both top and bottom interface layers. If support_material_interface_layers == 0, then neither top nor bottom interface layers are being extruded.
This commit is contained in:
parent
adcbe4347c
commit
00db3dc419
@ -118,7 +118,10 @@ public:
|
||||
private:
|
||||
Flow(float width, float height, float spacing, float nozzle_diameter, bool bridge) :
|
||||
m_width(width), m_height(height), m_spacing(spacing), m_nozzle_diameter(nozzle_diameter), m_bridge(bridge)
|
||||
{ assert(width >= height); }
|
||||
{
|
||||
// Gap fill violates this condition.
|
||||
//assert(width >= height);
|
||||
}
|
||||
|
||||
float m_width { 0 };
|
||||
float m_height { 0 };
|
||||
|
@ -428,7 +428,7 @@ const std::vector<std::string>& Preset::print_options()
|
||||
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||
"support_material_pattern", "support_material_with_sheath", "support_material_spacing",
|
||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
|
||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
|
||||
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
|
||||
"support_material_buildplate_only", "dont_support_bridges", "thick_bridges", "notes", "complete_objects", "extruder_clearance_radius",
|
||||
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder",
|
||||
|
@ -2299,7 +2299,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionInt(1));
|
||||
|
||||
def = this->add("support_material_interface_layers", coInt);
|
||||
def->label = L("Interface layers");
|
||||
def->label = L("Top interface layers");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("Number of interface layers to insert between the object(s) and support material.");
|
||||
def->sidetext = L("layers");
|
||||
@ -2307,6 +2307,16 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(3));
|
||||
|
||||
def = this->add("support_material_bottom_interface_layers", coInt);
|
||||
def->label = L("Bottom interface layers");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("Number of interface layers to insert between the object(s) and support material. "
|
||||
"Set to -1 to use support_material_interface_layers");
|
||||
def->sidetext = L("layers");
|
||||
def->min = -1;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(-1));
|
||||
|
||||
def = this->add("support_material_interface_spacing", coFloat);
|
||||
def->label = L("Interface pattern spacing");
|
||||
def->category = L("Support material");
|
||||
|
@ -509,6 +509,7 @@ public:
|
||||
ConfigOptionBool support_material_interface_contact_loops;
|
||||
ConfigOptionInt support_material_interface_extruder;
|
||||
ConfigOptionInt support_material_interface_layers;
|
||||
ConfigOptionInt support_material_bottom_interface_layers;
|
||||
// Spacing between interface lines (the hatching distance). Set zero to get a solid interface.
|
||||
ConfigOptionFloat support_material_interface_spacing;
|
||||
ConfigOptionFloatOrPercent support_material_interface_speed;
|
||||
@ -560,6 +561,7 @@ protected:
|
||||
OPT_PTR(support_material_extrusion_width);
|
||||
OPT_PTR(support_material_interface_extruder);
|
||||
OPT_PTR(support_material_interface_layers);
|
||||
OPT_PTR(support_material_bottom_interface_layers);
|
||||
OPT_PTR(support_material_interface_spacing);
|
||||
OPT_PTR(support_material_interface_speed);
|
||||
OPT_PTR(support_material_pattern);
|
||||
|
@ -587,6 +587,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "support_material_extruder"
|
||||
|| opt_key == "support_material_extrusion_width"
|
||||
|| opt_key == "support_material_interface_layers"
|
||||
|| opt_key == "support_material_bottom_interface_layers"
|
||||
|| opt_key == "support_material_interface_pattern"
|
||||
|| opt_key == "support_material_interface_contact_loops"
|
||||
|| opt_key == "support_material_interface_extruder"
|
||||
|
@ -2720,17 +2720,23 @@ std::pair<PrintObjectSupportMaterial::MyLayersPtr, PrintObjectSupportMaterial::M
|
||||
m_object_config->support_material_interface_extruder.value > 0 && m_print_config->filament_soluble.get_at(m_object_config->support_material_interface_extruder.value - 1) &&
|
||||
// Base extruder: Either "print with active extruder" not soluble.
|
||||
(m_object_config->support_material_extruder.value == 0 || ! m_print_config->filament_soluble.get_at(m_object_config->support_material_extruder.value - 1));
|
||||
int num_interface_layers = m_object_config->support_material_interface_layers.value;
|
||||
int num_base_interface_layers = soluble_interface_non_soluble_base ? std::min(num_interface_layers / 2, 2) : 0;
|
||||
int num_interface_layers_top = m_object_config->support_material_interface_layers;
|
||||
int num_interface_layers_bottom = m_object_config->support_material_bottom_interface_layers;
|
||||
if (num_interface_layers_bottom < 0)
|
||||
num_interface_layers_bottom = num_interface_layers_top;
|
||||
int num_base_interface_layers_top = soluble_interface_non_soluble_base ? std::min(num_interface_layers_top / 2, 2) : 0;
|
||||
int num_base_interface_layers_bottom = soluble_interface_non_soluble_base ? std::min(num_interface_layers_bottom / 2, 2) : 0;
|
||||
|
||||
if (! intermediate_layers.empty() && num_interface_layers > 1) {
|
||||
if (! intermediate_layers.empty() && (num_interface_layers_top > 1 || num_interface_layers_bottom > 1)) {
|
||||
// For all intermediate layers, collect top contact surfaces, which are not further than support_material_interface_layers.
|
||||
BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::generate_interface_layers() in parallel - start";
|
||||
// Since the intermediate layer index starts at zero the number of interface layer needs to be reduced by 1.
|
||||
-- num_interface_layers;
|
||||
int num_interface_layers_only = num_interface_layers - num_base_interface_layers;
|
||||
-- num_interface_layers_top;
|
||||
-- num_interface_layers_bottom;
|
||||
int num_interface_layers_only_top = num_interface_layers_top - num_base_interface_layers_top;
|
||||
int num_interface_layers_only_bottom = num_interface_layers_bottom - num_base_interface_layers_bottom;
|
||||
interface_layers.assign(intermediate_layers.size(), nullptr);
|
||||
if (num_base_interface_layers)
|
||||
if (num_base_interface_layers_top || num_base_interface_layers_bottom)
|
||||
base_interface_layers.assign(intermediate_layers.size(), nullptr);
|
||||
tbb::spin_mutex layer_storage_mutex;
|
||||
// Insert a new layer into base_interface_layers, if intersection with base exists.
|
||||
@ -2754,7 +2760,8 @@ std::pair<PrintObjectSupportMaterial::MyLayersPtr, PrintObjectSupportMaterial::M
|
||||
return &layer_new;
|
||||
};
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, int(intermediate_layers.size())),
|
||||
[&bottom_contacts, &top_contacts, &intermediate_layers, &insert_layer, num_interface_layers, num_base_interface_layers, num_interface_layers_only,
|
||||
[&bottom_contacts, &top_contacts, &intermediate_layers, &insert_layer,
|
||||
num_interface_layers_top, num_interface_layers_bottom, num_base_interface_layers_top, num_base_interface_layers_bottom, num_interface_layers_only_top, num_interface_layers_only_bottom,
|
||||
&interface_layers, &base_interface_layers](const tbb::blocked_range<int>& range) {
|
||||
// Gather the top / bottom contact layers intersecting with num_interface_layers resp. num_interface_layers_only intermediate layers above / below
|
||||
// this intermediate layer.
|
||||
@ -2765,45 +2772,51 @@ std::pair<PrintObjectSupportMaterial::MyLayersPtr, PrintObjectSupportMaterial::M
|
||||
auto num_intermediate = int(intermediate_layers.size());
|
||||
for (int idx_intermediate_layer = range.begin(); idx_intermediate_layer < range.end(); ++ idx_intermediate_layer) {
|
||||
MyLayer &intermediate_layer = *intermediate_layers[idx_intermediate_layer];
|
||||
// Top / bottom Z coordinate of a slab, over which we are collecting the top / bottom contact surfaces
|
||||
coordf_t top_z = intermediate_layers[std::min(num_intermediate - 1, idx_intermediate_layer + num_interface_layers - 1)]->print_z;
|
||||
coordf_t top_inteface_z = std::numeric_limits<coordf_t>::max();
|
||||
coordf_t bottom_z = intermediate_layers[std::max(0, idx_intermediate_layer - num_interface_layers + 1)]->bottom_z;
|
||||
coordf_t bottom_interface_z = - std::numeric_limits<coordf_t>::max();
|
||||
if (num_base_interface_layers > 0) {
|
||||
// Some base interface layers will be generated.
|
||||
if (num_interface_layers_only == 0)
|
||||
// Only base interface layers to generate.
|
||||
std::swap(top_inteface_z, bottom_interface_z);
|
||||
else {
|
||||
top_inteface_z = intermediate_layers[std::min(num_intermediate - 1, idx_intermediate_layer + num_interface_layers_only - 1)]->print_z;
|
||||
bottom_interface_z = intermediate_layers[std::max(0, idx_intermediate_layer - num_interface_layers_only)]->bottom_z;
|
||||
}
|
||||
}
|
||||
// Move idx_top_contact_first up until above the current print_z.
|
||||
idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const MyLayer *layer){ return layer->print_z >= intermediate_layer.print_z; }); // - EPSILON
|
||||
// Collect the top contact areas above this intermediate layer, below top_z.
|
||||
Polygons polygons_top_contact_projected_interface;
|
||||
Polygons polygons_top_contact_projected_base;
|
||||
for (int idx_top_contact = idx_top_contact_first; idx_top_contact < int(top_contacts.size()); ++ idx_top_contact) {
|
||||
const MyLayer &top_contact_layer = *top_contacts[idx_top_contact];
|
||||
//FIXME maybe this adds one interface layer in excess?
|
||||
if (top_contact_layer.bottom_z - EPSILON > top_z)
|
||||
break;
|
||||
polygons_append(top_contact_layer.bottom_z - EPSILON > top_inteface_z ? polygons_top_contact_projected_base : polygons_top_contact_projected_interface, top_contact_layer.polygons);
|
||||
}
|
||||
// Move idx_bottom_contact_first up until touching bottom_z.
|
||||
idx_bottom_contact_first = idx_higher_or_equal(bottom_contacts, idx_bottom_contact_first, [bottom_z](const MyLayer *layer){ return layer->print_z >= bottom_z - EPSILON; });
|
||||
// Collect the top contact areas above this intermediate layer, below top_z.
|
||||
Polygons polygons_bottom_contact_projected_interface;
|
||||
Polygons polygons_bottom_contact_projected_base;
|
||||
for (int idx_bottom_contact = idx_bottom_contact_first; idx_bottom_contact < int(bottom_contacts.size()); ++ idx_bottom_contact) {
|
||||
const MyLayer &bottom_contact_layer = *bottom_contacts[idx_bottom_contact];
|
||||
if (bottom_contact_layer.print_z - EPSILON > intermediate_layer.bottom_z)
|
||||
break;
|
||||
polygons_append(bottom_contact_layer.print_z - EPSILON > bottom_interface_z ? polygons_bottom_contact_projected_interface : polygons_bottom_contact_projected_base, bottom_contact_layer.polygons);
|
||||
if (num_interface_layers_top > -1) {
|
||||
// Top Z coordinate of a slab, over which we are collecting the top / bottom contact surfaces
|
||||
coordf_t top_z = intermediate_layers[std::min(num_intermediate - 1, idx_intermediate_layer + num_interface_layers_top - 1)]->print_z;
|
||||
coordf_t top_inteface_z = std::numeric_limits<coordf_t>::max();
|
||||
if (num_base_interface_layers_top > 0)
|
||||
// Some top base interface layers will be generated.
|
||||
top_inteface_z = num_interface_layers_only_top == 0 ?
|
||||
// Only base interface layers to generate.
|
||||
- std::numeric_limits<coordf_t>::max() :
|
||||
intermediate_layers[std::min(num_intermediate - 1, idx_intermediate_layer + num_interface_layers_only_top - 1)]->print_z;
|
||||
// Move idx_top_contact_first up until above the current print_z.
|
||||
idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const MyLayer *layer){ return layer->print_z >= intermediate_layer.print_z; }); // - EPSILON
|
||||
// Collect the top contact areas above this intermediate layer, below top_z.
|
||||
for (int idx_top_contact = idx_top_contact_first; idx_top_contact < int(top_contacts.size()); ++ idx_top_contact) {
|
||||
const MyLayer &top_contact_layer = *top_contacts[idx_top_contact];
|
||||
//FIXME maybe this adds one interface layer in excess?
|
||||
if (top_contact_layer.bottom_z - EPSILON > top_z)
|
||||
break;
|
||||
polygons_append(top_contact_layer.bottom_z - EPSILON > top_inteface_z ? polygons_top_contact_projected_base : polygons_top_contact_projected_interface, top_contact_layer.polygons);
|
||||
}
|
||||
}
|
||||
if (num_interface_layers_bottom > -1) {
|
||||
// Bottom Z coordinate of a slab, over which we are collecting the top / bottom contact surfaces
|
||||
coordf_t bottom_z = intermediate_layers[std::max(0, idx_intermediate_layer - num_interface_layers_bottom + 1)]->bottom_z;
|
||||
coordf_t bottom_interface_z = - std::numeric_limits<coordf_t>::max();
|
||||
if (num_base_interface_layers_bottom > 0)
|
||||
// Some bottom base interface layers will be generated.
|
||||
bottom_interface_z = num_interface_layers_only_bottom == 0 ?
|
||||
// Only base interface layers to generate.
|
||||
std::numeric_limits<coordf_t>::max() :
|
||||
intermediate_layers[std::max(0, idx_intermediate_layer - num_interface_layers_only_bottom)]->bottom_z;
|
||||
// Move idx_bottom_contact_first up until touching bottom_z.
|
||||
idx_bottom_contact_first = idx_higher_or_equal(bottom_contacts, idx_bottom_contact_first, [bottom_z](const MyLayer *layer){ return layer->print_z >= bottom_z - EPSILON; });
|
||||
// Collect the top contact areas above this intermediate layer, below top_z.
|
||||
for (int idx_bottom_contact = idx_bottom_contact_first; idx_bottom_contact < int(bottom_contacts.size()); ++ idx_bottom_contact) {
|
||||
const MyLayer &bottom_contact_layer = *bottom_contacts[idx_bottom_contact];
|
||||
if (bottom_contact_layer.print_z - EPSILON > intermediate_layer.bottom_z)
|
||||
break;
|
||||
polygons_append(bottom_contact_layer.print_z - EPSILON > bottom_interface_z ? polygons_bottom_contact_projected_interface : polygons_bottom_contact_projected_base, bottom_contact_layer.polygons);
|
||||
}
|
||||
}
|
||||
|
||||
MyLayer *interface_layer = nullptr;
|
||||
if (! polygons_bottom_contact_projected_interface.empty() || ! polygons_top_contact_projected_interface.empty()) {
|
||||
interface_layer = insert_layer(
|
||||
@ -3712,10 +3725,6 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||
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);
|
||||
@ -3725,6 +3734,12 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||
if (top_contact_layer.could_merge(interface_layer))
|
||||
top_contact_layer.merge(std::move(interface_layer));
|
||||
}
|
||||
if ((m_object_config->support_material_interface_layers == 0 || m_object_config->support_material_bottom_interface_layers == 0) && m_can_merge_support_regions) {
|
||||
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 0
|
||||
if ( ! interface_layer.empty() && ! base_layer.empty()) {
|
||||
|
@ -286,7 +286,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||
toggle_field(el, have_support_material);
|
||||
toggle_field("support_material_threshold", have_support_material_auto);
|
||||
|
||||
for (auto el : { "support_material_interface_spacing", "support_material_interface_extruder",
|
||||
for (auto el : { "support_material_bottom_interface_layers", "support_material_interface_spacing", "support_material_interface_extruder",
|
||||
"support_material_interface_speed", "support_material_interface_contact_loops" })
|
||||
toggle_field(el, have_support_material && have_support_interface);
|
||||
toggle_field("support_material_synchronize_layers", have_support_soluble);
|
||||
|
@ -1512,6 +1512,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("support_material_spacing", category_path + "pattern-spacing-0-inf");
|
||||
optgroup->append_single_option_line("support_material_angle", category_path + "pattern-angle");
|
||||
optgroup->append_single_option_line("support_material_interface_layers", category_path + "interface-layers");
|
||||
optgroup->append_single_option_line("support_material_bottom_interface_layers", category_path + "interface-layers");
|
||||
optgroup->append_single_option_line("support_material_interface_pattern", category_path + "interface-pattern");
|
||||
optgroup->append_single_option_line("support_material_interface_spacing", category_path + "interface-pattern-spacing");
|
||||
optgroup->append_single_option_line("support_material_interface_contact_loops", category_path + "interface-loops");
|
||||
|
Loading…
Reference in New Issue
Block a user