Organic Supports: support_tree_branch_diameter_double_wall

to control when the 2nd wall kicks in.
This commit is contained in:
Vojtech Bubnik 2023-05-09 10:46:56 +02:00
parent daa9bf7cd9
commit 84db6356b3
9 changed files with 41 additions and 19 deletions

View file

@ -444,7 +444,8 @@ static std::vector<std::string> s_Preset_print_options {
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
"support_material_contact_distance", "support_material_bottom_contact_distance",
"support_material_buildplate_only",
"support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter", "support_tree_branch_diameter_angle", "support_tree_top_rate", "support_tree_branch_distance", "support_tree_tip_diameter",
"support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter", "support_tree_branch_diameter_angle", "support_tree_branch_diameter_double_wall",
"support_tree_top_rate", "support_tree_branch_distance", "support_tree_tip_diameter",
"dont_support_bridges", "thick_bridges", "notes", "complete_objects", "extruder_clearance_radius",
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "gcode_substitutions", "perimeter_extruder",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",

View file

@ -2939,6 +2939,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(5));
def = this->add("support_tree_branch_diameter_double_wall", coFloat);
def->label = L("Branch Diameter with double walls");
def->category = L("Support material");
// TRN PrintSettings: "Organic supports" > "Branch Diameter"
def->tooltip = L("Branches with area larger than the area of a circle of this diameter will be printed with double walls for stability. "
"Set this value to zero for no double walls.");
def->sidetext = L("mm");
def->min = 0;
def->max = 100.f;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(3));
// Tree Support Branch Distance
// How far apart the branches need to be when they touch the model. Making this distance small will cause
// the tree support to touch the model at more points, causing better overhang but making support harder to remove.

View file

@ -554,6 +554,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, support_tree_angle_slow))
((ConfigOptionFloat, support_tree_branch_diameter))
((ConfigOptionFloat, support_tree_branch_diameter_angle))
((ConfigOptionFloat, support_tree_branch_diameter_double_wall))
((ConfigOptionPercent, support_tree_top_rate))
((ConfigOptionFloat, support_tree_branch_distance))
((ConfigOptionFloat, support_tree_tip_diameter))

View file

@ -712,6 +712,7 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "support_tree_angle_slow"
|| opt_key == "support_tree_branch_diameter"
|| opt_key == "support_tree_branch_diameter_angle"
|| opt_key == "support_tree_branch_diameter_double_wall"
|| opt_key == "support_tree_top_rate"
|| opt_key == "support_tree_branch_distance"
|| opt_key == "support_tree_tip_diameter"

View file

@ -537,7 +537,8 @@ static Polylines draw_perimeters(const ExPolygon &expoly, double clip_length)
static inline void tree_supports_generate_paths(
ExtrusionEntitiesPtr &dst,
const Polygons &polygons,
const Flow &flow)
const Flow &flow,
const SupportParameters &support_params)
{
// Offset expolygon inside, returns number of expolygons collected (0 or 1).
// Vertices of output paths are marked with Z = source contour index of the expoly.
@ -634,21 +635,21 @@ static inline void tree_supports_generate_paths(
ClipperLib_Z::Paths anchor_candidates;
for (ExPolygon& expoly : closing_ex(polygons, float(SCALED_EPSILON), float(SCALED_EPSILON + 0.5 * flow.scaled_width()))) {
std::unique_ptr<ExtrusionEntityCollection> eec;
double area = expoly.area();
if (area > sqr(scaled<double>(5.))) {
eec = std::make_unique<ExtrusionEntityCollection>();
// Don't reoder internal / external loops of the same island, always start with the internal loop.
eec->no_sort = true;
// Make the tree branch stable by adding another perimeter.
ExPolygons level2 = offset2_ex({ expoly }, -1.5 * flow.scaled_width(), 0.5 * flow.scaled_width());
if (level2.size() == 1) {
Polylines polylines;
extrusion_entities_append_paths(eec->entities, draw_perimeters(expoly, clip_length), ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
// Disable reversal of the path, always start with the anchor, always print CCW.
false);
expoly = level2.front();
if (support_params.tree_branch_diameter_double_wall_area_scaled > 0)
if (double area = expoly.area(); area > support_params.tree_branch_diameter_double_wall_area_scaled) {
eec = std::make_unique<ExtrusionEntityCollection>();
// Don't reoder internal / external loops of the same island, always start with the internal loop.
eec->no_sort = true;
// Make the tree branch stable by adding another perimeter.
ExPolygons level2 = offset2_ex({ expoly }, -1.5 * flow.scaled_width(), 0.5 * flow.scaled_width());
if (level2.size() == 1) {
Polylines polylines;
extrusion_entities_append_paths(eec->entities, draw_perimeters(expoly, clip_length), ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
// Disable reversal of the path, always start with the anchor, always print CCW.
false);
expoly = level2.front();
}
}
}
// Try to produce one more perimeter to place the seam anchor.
// First genrate a 2nd perimeter loop as a source for anchor candidates.
@ -1531,7 +1532,7 @@ void generate_support_toolpaths(
support_params.with_sheath, false);
}
if (! tree_polygons.empty())
tree_supports_generate_paths(support_layer.support_fills.entities, tree_polygons, flow);
tree_supports_generate_paths(support_layer.support_fills.entities, tree_polygons, flow, support_params);
}
Fill *filler = filler_interface.get();
@ -1790,7 +1791,7 @@ void generate_support_toolpaths(
sheath = true;
no_sort = true;
} else if (config.support_material_style == SupportMaterialStyle::smsOrganic) {
tree_supports_generate_paths(base_layer.extrusions, base_layer.polygons_to_extrude(), flow);
tree_supports_generate_paths(base_layer.extrusions, base_layer.polygons_to_extrude(), flow, support_params);
done = true;
}
if (! done)

View file

@ -137,6 +137,8 @@ SupportParameters::SupportParameters(const PrintObject &object)
assert(slicing_params.interface_raft_layers == 0);
assert(slicing_params.raft_layers() == 0);
}
this->tree_branch_diameter_double_wall_area_scaled = 0.25 * sqr(scaled<double>(object_config.support_tree_branch_diameter_double_wall.value)) * M_PI;
}
} // namespace Slic3r

View file

@ -77,6 +77,8 @@ struct SupportParameters {
InfillPattern contact_fill_pattern;
// Shall the sparse (base) layers be printed with a single perimeter line (sheath) for robustness?
bool with_sheath;
// Branches of organic supports with area larger than this threshold will be extruded with double lines.
double tree_branch_diameter_double_wall_area_scaled;
float raft_angle_1st_layer;
float raft_angle_base;

View file

@ -291,7 +291,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
(config->opt_bool("support_material") ||
config->opt_int("support_material_enforce_layers") > 0);
for (const std::string& key : { "support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter",
"support_tree_branch_diameter_angle", "support_tree_tip_diameter", "support_tree_branch_distance", "support_tree_top_rate" })
"support_tree_branch_diameter_angle", "support_tree_branch_diameter_double_wall",
"support_tree_tip_diameter", "support_tree_branch_distance", "support_tree_top_rate" })
toggle_field(key, has_organic_supports);
for (auto el : { "support_material_bottom_interface_layers", "support_material_interface_spacing", "support_material_interface_extruder",

View file

@ -1536,6 +1536,7 @@ void TabPrint::build()
optgroup->append_single_option_line("support_tree_angle_slow", category_path + "tree_angle_slow");
optgroup->append_single_option_line("support_tree_branch_diameter", category_path + "tree_branch_diameter");
optgroup->append_single_option_line("support_tree_branch_diameter_angle", category_path + "tree_branch_diameter_angle");
optgroup->append_single_option_line("support_tree_branch_diameter_double_wall", category_path + "tree_branch_diameter_double_wall");
optgroup->append_single_option_line("support_tree_tip_diameter", category_path + "tree_tip_diameter");
optgroup->append_single_option_line("support_tree_branch_distance", category_path + "tree_branch_distance");
optgroup->append_single_option_line("support_tree_top_rate", category_path + "tree_top_rate");