mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 19:01:02 +00:00
Combine brims option (Prusa style brims) (#12343)
* Union ex brims Revert "Union ex brims" This reverts commit bbc9a39faf318dc2df093eb2bdcebf19a4162fe9. Update Brim.cpp * dont repeat paths * Update Brim.cpp * multimaterial brim independiente * Normal brim if is by object * fix print order * cleaning 1 * cleaning 2 * Normal brim if multimaterial on first layer * fix artifact * combine_brim optional refactoring * refactoring gcode.cpp * refactoring brim.cpp Update Brim.cpp * Remove multimaterial first-layer check for brims Stop detecting extruders used on the first layer and remove the is_multimaterial_first_layer guard. Simplify can_combine_brims to only consider combine_brims and whether printing is ByObject, allowing brims to be combined across extruders unless printing by object or combine_brims is disabled. Cleans up unused code and simplifies brim-generation conditions. * Remove material specification from unified brim comment * Update PrintConfig.cpp
This commit is contained in:
+57
-10
@@ -928,16 +928,63 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_
|
|||||||
for (size_t iia = 0; iia < islands_area.size(); ++iia)
|
for (size_t iia = 0; iia < islands_area.size(); ++iia)
|
||||||
islands_area[iia].translate(plate_shift);
|
islands_area[iia].translate(plate_shift);
|
||||||
|
|
||||||
for (auto iter = brimAreaMap.begin(); iter != brimAreaMap.end(); ++iter) {
|
const bool combine_brims = print.config().combine_brims.value;
|
||||||
if (!iter->second.empty()) {
|
const bool is_by_object = (print.config().print_sequence == PrintSequence::ByObject);
|
||||||
brimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
|
const bool can_combine_brims = combine_brims && !is_by_object;
|
||||||
};
|
|
||||||
}
|
if (!can_combine_brims) {
|
||||||
for (auto iter = supportBrimAreaMap.begin(); iter != supportBrimAreaMap.end(); ++iter) {
|
// Orca: Generate brims separately for each object when multiple extruders are used
|
||||||
if (!iter->second.empty()) {
|
for (auto iter = brimAreaMap.begin(); iter != brimAreaMap.end(); ++iter) {
|
||||||
supportBrimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
|
if (!iter->second.empty()) {
|
||||||
};
|
brimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (auto iter = supportBrimAreaMap.begin(); iter != supportBrimAreaMap.end(); ++iter) {
|
||||||
|
if (!iter->second.empty()) {
|
||||||
|
supportBrimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Orca: Unified brim mode (non-sequential printing)
|
||||||
|
ExPolygons all_brims_merged;
|
||||||
|
std::vector<ObjectID> brim_object_ids;
|
||||||
|
|
||||||
|
// Add all object brims
|
||||||
|
for (auto& [obj_id, brims] : brimAreaMap) {
|
||||||
|
if (!brims.empty()) {
|
||||||
|
expolygons_append(all_brims_merged, brims);
|
||||||
|
brim_object_ids.push_back(obj_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!all_brims_merged.empty()) {
|
||||||
|
// Merge all brims into a single continuous area
|
||||||
|
all_brims_merged = union_ex(all_brims_merged);
|
||||||
|
|
||||||
|
// Apply a tiny morphological cleanup to reduce boolean-union micro-artifacts.
|
||||||
|
const float brim_cleanup_delta = std::max(float(scaled_resolution), float(SCALED_EPSILON));
|
||||||
|
all_brims_merged = offset2_ex(all_brims_merged, brim_cleanup_delta, -brim_cleanup_delta, jtRound, scaled_resolution);
|
||||||
|
|
||||||
|
// Generate infill once for the merged brim area.
|
||||||
|
ExtrusionEntityCollection merged_brim = makeBrimInfill(all_brims_merged, print, islands_area);
|
||||||
|
|
||||||
|
// In unified mode, assign the merged brim to a deterministic carrier object.
|
||||||
|
// Pick the first object in print order that actually contributed brim area.
|
||||||
|
ObjectID carrier_id;
|
||||||
|
bool carrier_found = false;
|
||||||
|
for (const auto& [obj_id, _extruder] : objPrintVec) {
|
||||||
|
if (std::find(brim_object_ids.begin(), brim_object_ids.end(), obj_id) != brim_object_ids.end()) {
|
||||||
|
carrier_id = obj_id;
|
||||||
|
carrier_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!carrier_found)
|
||||||
|
carrier_id = brim_object_ids.front();
|
||||||
|
|
||||||
|
brimMap[carrier_id] = std::move(merged_brim);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|||||||
@@ -4993,6 +4993,39 @@ LayerResult GCode::process_layer(
|
|||||||
bool has_insert_wrapping_detection_gcode = false;
|
bool has_insert_wrapping_detection_gcode = false;
|
||||||
|
|
||||||
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
|
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
|
||||||
|
// Orca: Print unified global brim before any object.
|
||||||
|
// Only do this if `combine_brims` is enabled and we are printing by layer.
|
||||||
|
if (first_layer && sequence_by_layer && m_config.combine_brims && !print.m_brimMap.empty()) {
|
||||||
|
const ObjectID unified_object_id = [&]() -> ObjectID {
|
||||||
|
ObjectID id;
|
||||||
|
bool found = false;
|
||||||
|
for (const auto& [obj_id, brim] : print.m_brimMap) {
|
||||||
|
const bool has_printable_entities = std::any_of(brim.entities.begin(), brim.entities.end(),
|
||||||
|
[](const ExtrusionEntity* ee) { return ee != nullptr; });
|
||||||
|
if (!has_printable_entities)
|
||||||
|
continue;
|
||||||
|
if (found)
|
||||||
|
return ObjectID();
|
||||||
|
id = obj_id;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
return found ? id : ObjectID();
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (unified_object_id.valid()) {
|
||||||
|
const auto it = print.m_brimMap.find(unified_object_id);
|
||||||
|
if (it != print.m_brimMap.end()) {
|
||||||
|
this->set_origin(0., 0.);
|
||||||
|
for (const ExtrusionEntity* ee : it->second.entities)
|
||||||
|
if (ee != nullptr)
|
||||||
|
gcode += this->extrude_entity(*ee, "brim", m_config.support_speed.value);
|
||||||
|
|
||||||
|
// Mark brim as printed for this object to avoid per-object brim emission later.
|
||||||
|
this->m_objsWithBrim.erase(unified_object_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int extruder_id : layer_tools.extruders)
|
for (unsigned int extruder_id : layer_tools.extruders)
|
||||||
{
|
{
|
||||||
if (print.config().skirt_type == stCombined && !print.skirt().empty())
|
if (print.config().skirt_type == stCombined && !print.skirt().empty())
|
||||||
|
|||||||
@@ -904,7 +904,7 @@ static std::vector<std::string> s_Preset_print_options {
|
|||||||
"top_surface_speed", "support_speed", "support_object_xy_distance", "support_object_first_layer_gap", "support_interface_speed",
|
"top_surface_speed", "support_speed", "support_object_xy_distance", "support_object_first_layer_gap", "support_interface_speed",
|
||||||
"bridge_speed", "internal_bridge_speed", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed",
|
"bridge_speed", "internal_bridge_speed", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed",
|
||||||
"outer_wall_acceleration", "initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle", "skirt_height","single_loop_draft_shield", "draft_shield",
|
"outer_wall_acceleration", "initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle", "skirt_height","single_loop_draft_shield", "draft_shield",
|
||||||
"brim_width", "brim_object_gap", "brim_use_efc_outline", "brim_type", "brim_ears_max_angle", "brim_ears_detection_length", "enable_support", "support_type", "support_threshold_angle", "support_threshold_overlap","enforce_support_layers",
|
"brim_width", "brim_object_gap", "brim_use_efc_outline", "combine_brims", "brim_type", "brim_ears_max_angle", "brim_ears_detection_length", "enable_support", "support_type", "support_threshold_angle", "support_threshold_overlap","enforce_support_layers",
|
||||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||||
"support_base_pattern", "support_base_pattern_spacing", "support_expansion", "support_style",
|
"support_base_pattern", "support_base_pattern_spacing", "support_expansion", "support_style",
|
||||||
// BBS
|
// BBS
|
||||||
|
|||||||
@@ -1594,6 +1594,13 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionBool(false));
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
|
def = this->add("combine_brims", coBool);
|
||||||
|
def->label = L("Combine brims");
|
||||||
|
def->category = L("Support");
|
||||||
|
def->tooltip = L("Combine multiple brims into one when they are close to each other. This can improve brim adhesion.");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
def = this->add("brim_ears", coBool);
|
def = this->add("brim_ears", coBool);
|
||||||
def->label = L("Brim ears");
|
def->label = L("Brim ears");
|
||||||
def->category = L("Support");
|
def->category = L("Support");
|
||||||
|
|||||||
@@ -1550,6 +1550,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||||||
((ConfigOptionString, thumbnails))
|
((ConfigOptionString, thumbnails))
|
||||||
// BBS: move from PrintObjectConfig
|
// BBS: move from PrintObjectConfig
|
||||||
((ConfigOptionBool, independent_support_layer_height))
|
((ConfigOptionBool, independent_support_layer_height))
|
||||||
|
((ConfigOptionBool, combine_brims))
|
||||||
// SoftFever
|
// SoftFever
|
||||||
((ConfigOptionPercents, filament_shrink))
|
((ConfigOptionPercents, filament_shrink))
|
||||||
((ConfigOptionPercents, filament_shrinkage_compensation_z))
|
((ConfigOptionPercents, filament_shrinkage_compensation_z))
|
||||||
|
|||||||
@@ -706,6 +706,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||||||
bool have_brim = (config->opt_enum<BrimType>("brim_type") != btNoBrim);
|
bool have_brim = (config->opt_enum<BrimType>("brim_type") != btNoBrim);
|
||||||
toggle_field("brim_object_gap", have_brim);
|
toggle_field("brim_object_gap", have_brim);
|
||||||
toggle_field("brim_use_efc_outline", have_brim);
|
toggle_field("brim_use_efc_outline", have_brim);
|
||||||
|
toggle_field("combine_brims", have_brim);
|
||||||
bool have_brim_width = (config->opt_enum<BrimType>("brim_type") != btNoBrim) && config->opt_enum<BrimType>("brim_type") != btAutoBrim &&
|
bool have_brim_width = (config->opt_enum<BrimType>("brim_type") != btNoBrim) && config->opt_enum<BrimType>("brim_type") != btAutoBrim &&
|
||||||
config->opt_enum<BrimType>("brim_type") != btPainted;
|
config->opt_enum<BrimType>("brim_type") != btPainted;
|
||||||
toggle_field("brim_width", have_brim_width);
|
toggle_field("brim_width", have_brim_width);
|
||||||
|
|||||||
@@ -4809,7 +4809,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||||||
"extruder_clearance_radius",
|
"extruder_clearance_radius",
|
||||||
"extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
|
"extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
|
||||||
"nozzle_height", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle",
|
"nozzle_height", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle",
|
||||||
"brim_width", "brim_object_gap", "brim_use_efc_outline", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
|
"brim_width", "brim_object_gap", "brim_use_efc_outline", "combine_brims", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
|
||||||
"enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", "prime_tower_enable_framework",
|
"enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", "prime_tower_enable_framework",
|
||||||
"prime_tower_infill_gap", "prime_volume",
|
"prime_tower_infill_gap", "prime_volume",
|
||||||
"extruder_colour", "filament_colour", "filament_type", "material_colour", "printable_height", "extruder_printable_height", "printer_model", "printer_technology",
|
"extruder_colour", "filament_colour", "filament_type", "material_colour", "printable_height", "extruder_printable_height", "printer_model", "printer_technology",
|
||||||
|
|||||||
@@ -2658,6 +2658,7 @@ void TabPrint::build()
|
|||||||
optgroup->append_single_option_line("brim_width", "others_settings_brim#width");
|
optgroup->append_single_option_line("brim_width", "others_settings_brim#width");
|
||||||
optgroup->append_single_option_line("brim_object_gap", "others_settings_brim#brim-object-gap");
|
optgroup->append_single_option_line("brim_object_gap", "others_settings_brim#brim-object-gap");
|
||||||
optgroup->append_single_option_line("brim_use_efc_outline", "others_settings_brim#brim-use-efc-outline");
|
optgroup->append_single_option_line("brim_use_efc_outline", "others_settings_brim#brim-use-efc-outline");
|
||||||
|
optgroup->append_single_option_line("combine_brims", "others_settings_brim#combine-brim");
|
||||||
optgroup->append_single_option_line("brim_ears_max_angle", "others_settings_brim#ear-max-angle");
|
optgroup->append_single_option_line("brim_ears_max_angle", "others_settings_brim#ear-max-angle");
|
||||||
optgroup->append_single_option_line("brim_ears_detection_length", "others_settings_brim#ear-detection-radius");
|
optgroup->append_single_option_line("brim_ears_detection_length", "others_settings_brim#ear-detection-radius");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user