mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-12-24 00:28:38 -07:00
Alternate internal walls
This commit is contained in:
parent
014e9bbd04
commit
7ae9373368
10 changed files with 131 additions and 53 deletions
|
|
@ -5385,7 +5385,16 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
float seam_overhang = std::numeric_limits<float>::lowest();
|
||||
if (!m_config.spiral_mode && description == "perimeter") {
|
||||
assert(m_layer != nullptr);
|
||||
m_seam_placer.place_seam(m_layer, loop, last_pos, seam_overhang);
|
||||
bool reverse = false;
|
||||
|
||||
if (region_perimeters.size() > 1) {
|
||||
ExtrusionLoop* p0 = dynamic_cast<ExtrusionLoop*>(region_perimeters[0]);
|
||||
ExtrusionLoop* p1 = dynamic_cast<ExtrusionLoop*>(region_perimeters[1]);
|
||||
if (p0 && p1)
|
||||
reverse = p0->is_clockwise() != p1->is_clockwise();
|
||||
}
|
||||
|
||||
m_seam_placer.place_seam(m_layer, loop, last_pos, seam_overhang, reverse);
|
||||
} else
|
||||
loop.split_at(last_pos, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -1494,7 +1494,7 @@ void SeamPlacer::init(const Print &print, std::function<void(void)> throw_if_can
|
|||
}
|
||||
|
||||
void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop,
|
||||
const Point &last_pos, float& overhang) const {
|
||||
const Point &last_pos, float& overhang, bool reverse) const {
|
||||
using namespace SeamPlacerImpl;
|
||||
const PrintObject *po = layer->object();
|
||||
// Must not be called with supprot layer.
|
||||
|
|
@ -1596,8 +1596,11 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop,
|
|||
|
||||
//lastly, for internal perimeters, do the staggering if requested
|
||||
if (po->config().staggered_inner_seams && loop.length() > 0.0) {
|
||||
//fix depth, it is sometimes strongly underestimated
|
||||
depth = std::max(loop.paths[projected_point.path_idx].width, depth);
|
||||
if (!reverse)
|
||||
//fix depth, it is sometimes strongly underestimated
|
||||
depth = std::max(loop.paths[projected_point.path_idx].width, depth);
|
||||
else
|
||||
depth = std::min(4. + ((double)rand())/RAND_MAX*2., loop.length() * SCALING_FACTOR / 2);
|
||||
|
||||
while (depth > 0.0f) {
|
||||
auto next_point = get_next_loop_point(projected_point);
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ public:
|
|||
|
||||
void init(const Print &print, std::function<void(void)> throw_if_canceled_func);
|
||||
|
||||
void place_seam(const Layer *layer, ExtrusionLoop &loop, const Point &last_pos, float& overhang) const;
|
||||
void place_seam(const Layer *layer, ExtrusionLoop &loop, const Point &last_pos, float& overhang, bool reverse) const;
|
||||
private:
|
||||
void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info);
|
||||
void calculate_candidates_visibility(const PrintObject *po,
|
||||
|
|
|
|||
|
|
@ -1092,30 +1092,85 @@ void PerimeterGenerator::apply_extra_perimeters(ExPolygons &infill_area)
|
|||
}
|
||||
|
||||
// Reorient loop direction
|
||||
static void reorient_perimeters(ExtrusionEntityCollection &entities, bool steep_overhang_contour, bool steep_overhang_hole, bool reverse_internal_only)
|
||||
static void reorient_walls(ExtrusionEntitiesPtr &entities, bool steep_overhang_contour, bool steep_overhang_hole,
|
||||
bool alternate_internal_walls)
|
||||
{
|
||||
if (steep_overhang_hole || steep_overhang_contour) {
|
||||
for (auto entity : entities) {
|
||||
if (steep_overhang_contour || steep_overhang_hole || alternate_internal_walls) {
|
||||
ExtrusionEntitiesPtr ordered = entities;
|
||||
|
||||
if (alternate_internal_walls) {
|
||||
auto entity = *ordered.begin();
|
||||
if (entity->is_loop()) {
|
||||
ExtrusionLoop *eloop = static_cast<ExtrusionLoop *>(entity);
|
||||
// Only reverse when needed
|
||||
bool need_reverse = ((eloop->loop_role() & elrHole) == elrHole) ? steep_overhang_hole : steep_overhang_contour;
|
||||
|
||||
bool isExternal = false;
|
||||
if(reverse_internal_only){
|
||||
for(auto path : eloop->paths){
|
||||
if(path.role() == erExternalPerimeter){
|
||||
isExternal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (auto path : eloop->paths) {
|
||||
if (path.role() == erPerimeter)
|
||||
std::reverse(ordered.begin(), ordered.end());
|
||||
break;
|
||||
}
|
||||
|
||||
if (need_reverse && !isExternal) {
|
||||
eloop->reverse();
|
||||
}
|
||||
|
||||
if (ordered.size() > 2) {
|
||||
entity = *ordered.begin();
|
||||
if (entity->is_loop()) {
|
||||
ExtrusionLoop *eloop = static_cast<ExtrusionLoop *>(entity);
|
||||
for (auto path : eloop->paths) {
|
||||
if (path.role() == erPerimeter)
|
||||
std::swap(*ordered.begin(), *(ordered.begin()+1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int reverse_count = 0;
|
||||
for (auto entity : ordered) {
|
||||
if (entity->is_loop()) {
|
||||
ExtrusionLoop *eloop = static_cast<ExtrusionLoop *>(entity);
|
||||
for(auto path : eloop->paths){
|
||||
if(path.role() == erExternalPerimeter){
|
||||
if (((eloop->loop_role() & elrHole) == elrHole) ? steep_overhang_hole : steep_overhang_contour) {
|
||||
eloop->reverse();
|
||||
reverse_count++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(path.role() == erPerimeter && alternate_internal_walls){
|
||||
reverse_count++;
|
||||
if (reverse_count % 2 == 1)
|
||||
eloop->reverse();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reorient_perimeters(ExtrusionEntityCollection& entities, bool steep_overhang_contour, bool steep_overhang_hole,
|
||||
bool alternate_internal_walls)
|
||||
{
|
||||
alternate_internal_walls = alternate_internal_walls && entities.size() > 1;
|
||||
|
||||
if (steep_overhang_contour || steep_overhang_hole || alternate_internal_walls) {
|
||||
|
||||
if (alternate_internal_walls) {
|
||||
ExtrusionEntitiesPtr walls;
|
||||
|
||||
for (auto entity : entities) {
|
||||
if (entity->is_loop()) {
|
||||
ExtrusionLoop *eloop = static_cast<ExtrusionLoop *>(entity);
|
||||
|
||||
if (walls.empty() || eloop->loop_role() == static_cast<ExtrusionLoop *>(walls.back())->loop_role())
|
||||
walls.push_back(entity);
|
||||
else {
|
||||
reorient_walls(walls, steep_overhang_contour, steep_overhang_hole, alternate_internal_walls);
|
||||
walls.clear();
|
||||
walls.push_back(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
reorient_walls(walls, steep_overhang_contour, steep_overhang_hole, alternate_internal_walls);
|
||||
} else
|
||||
reorient_walls(entities.entities, steep_overhang_contour, steep_overhang_hole, alternate_internal_walls);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1427,10 +1482,14 @@ void PerimeterGenerator::process_classic()
|
|||
}
|
||||
ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls, steep_overhang_contour, steep_overhang_hole);
|
||||
// All walls are counter-clockwise initially, so we don't need to reorient it if that's what we want
|
||||
if (config->overhang_reverse) {
|
||||
if (config->overhang_reverse || this->config->alternate_internal_walls) {
|
||||
if (!config->overhang_reverse) {
|
||||
// Skip steep overhang reverse if not specified
|
||||
steep_overhang_contour = false;
|
||||
steep_overhang_hole = false;
|
||||
}
|
||||
reorient_perimeters(entities, steep_overhang_contour, steep_overhang_hole,
|
||||
// Reverse internal only if the wall direction is auto
|
||||
this->config->overhang_reverse_internal_only);
|
||||
this->config->alternate_internal_walls);
|
||||
}
|
||||
|
||||
// if brim will be printed, reverse the order of perimeters so that
|
||||
|
|
@ -2450,14 +2509,19 @@ void PerimeterGenerator::process_arachne()
|
|||
bool steep_overhang_contour = false;
|
||||
bool steep_overhang_hole = false;
|
||||
if (!config->overhang_reverse) {
|
||||
// Skip steep overhang detection no reverse is specified
|
||||
// Skip steep overhang detection if no reverse is specified
|
||||
steep_overhang_contour = true;
|
||||
steep_overhang_hole = true;
|
||||
}
|
||||
if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(*this, ordered_extrusions, steep_overhang_contour, steep_overhang_hole); !extrusion_coll.empty()) {
|
||||
if (config->overhang_reverse) {
|
||||
|
||||
if (config->overhang_reverse || this->config->alternate_internal_walls){
|
||||
if (!config->overhang_reverse) {
|
||||
steep_overhang_contour = false;
|
||||
steep_overhang_hole = false;
|
||||
}
|
||||
reorient_perimeters(extrusion_coll, steep_overhang_contour, steep_overhang_hole,
|
||||
this->config->overhang_reverse_internal_only);
|
||||
this->config->alternate_internal_walls);
|
||||
}
|
||||
this->loops->append(extrusion_coll);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -883,7 +883,7 @@ bool Preset::has_cali_lines(PresetBundle* preset_bundle)
|
|||
static std::vector<std::string> s_Preset_print_options {
|
||||
"layer_height", "initial_layer_print_height", "wall_loops", "alternate_extra_wall", "slice_closing_radius", "spiral_mode", "spiral_mode_smooth", "spiral_mode_max_xy_smoothing", "spiral_starting_flow_ratio", "spiral_finishing_flow_ratio", "slicing_mode",
|
||||
"top_shell_layers", "top_shell_thickness", "top_surface_density", "bottom_surface_density", "bottom_shell_layers", "bottom_shell_thickness",
|
||||
"extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall", "overhang_reverse", "overhang_reverse_threshold","overhang_reverse_internal_only", "wall_direction",
|
||||
"extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall", "overhang_reverse", "overhang_reverse_threshold", "wall_direction", "alternate_internal_walls",
|
||||
"seam_position", "staggered_inner_seams", "wall_sequence", "is_infill_first", "sparse_infill_density","fill_multiline", "sparse_infill_pattern", "lateral_lattice_angle_1", "lateral_lattice_angle_2", "infill_overhang_angle", "top_surface_pattern", "bottom_surface_pattern",
|
||||
"infill_direction", "solid_infill_direction", "counterbore_hole_bridging","infill_shift_step", "sparse_infill_rotate_template", "solid_infill_rotate_template", "symmetric_infill_y_axis","skeleton_infill_density", "infill_lock_depth", "skin_infill_depth", "skin_infill_density",
|
||||
"align_infill_direction_to_model", "extra_solid_infills",
|
||||
|
|
|
|||
|
|
@ -1377,19 +1377,6 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("overhang_reverse_internal_only", coBool);
|
||||
def->label = L("Reverse only internal perimeters");
|
||||
def->full_label = L("Reverse only internal perimeters");
|
||||
def->category = L("Quality");
|
||||
def->tooltip = L("Apply the reverse perimeters logic only on internal perimeters.\n\n"
|
||||
"This setting greatly reduces part stresses as they are now distributed in alternating directions. "
|
||||
"This should reduce part warping while also maintaining external wall quality. "
|
||||
"This feature can be very useful for warp prone material, like ABS/ASA, and also for elastic filaments, like TPU and Silk PLA. "
|
||||
"It can also help reduce warping on floating regions over supports.\n\nFor this setting to be the most effective, "
|
||||
"it is recommended to set the Reverse Threshold to 0 so that all internal walls print in alternating directions on even layers irrespective of their overhang degree.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("counterbore_hole_bridging", coEnum);
|
||||
def->label = L("Bridge counterbore holes");
|
||||
def->category = L("Quality");
|
||||
|
|
@ -1993,6 +1980,14 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<WallDirection>(WallDirection::CounterClockwise));
|
||||
|
||||
def = this->add("alternate_internal_walls", coBool);
|
||||
def->label = L("Reverse internal perimeters");
|
||||
def->full_label = L("Reverse internal perimeters");
|
||||
def->category = L("Quality");
|
||||
def->tooltip = L("Alternate each internal perimeter direction.\n\nThis setting greatly reduces part stresses as they are now distributed in alternating directions. This should reduce part warping while also maintaining external wall quality. This feature can be very useful for warp prone material, like ABS/ASA, and also for elastic filaments, like TPU and Silk PLA. It can also help reduce warping on floating regions over supports.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("extruder", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Extruder");
|
||||
|
|
@ -7512,6 +7507,10 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
|||
else if (opt_key == "wall_direction" && value == "auto") {
|
||||
value = "ccw";
|
||||
}
|
||||
else if (opt_key == "overhang_reverse_internal_only" && value == "1") {
|
||||
opt_key = "alternate_internal_walls";
|
||||
value = "1";
|
||||
}
|
||||
|
||||
// Ignore the following obsolete configuration keys:
|
||||
static std::set<std::string> ignore = {
|
||||
|
|
|
|||
|
|
@ -1145,13 +1145,13 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloatOrPercent, hole_to_polyhole_threshold))
|
||||
((ConfigOptionBool, hole_to_polyhole_twisted))
|
||||
((ConfigOptionBool, overhang_reverse))
|
||||
((ConfigOptionBool, overhang_reverse_internal_only))
|
||||
((ConfigOptionFloatOrPercent, overhang_reverse_threshold))
|
||||
((ConfigOptionEnum<CounterboreHoleBridgingOption>, counterbore_hole_bridging))
|
||||
((ConfigOptionEnum<WallSequence>, wall_sequence))
|
||||
((ConfigOptionBool, is_infill_first))
|
||||
((ConfigOptionBool, small_area_infill_flow_compensation))
|
||||
((ConfigOptionEnum<WallDirection>, wall_direction))
|
||||
((ConfigOptionBool, alternate_internal_walls))
|
||||
|
||||
// Orca: flow ratios
|
||||
((ConfigOptionBool, set_other_flow_ratios))
|
||||
|
|
|
|||
|
|
@ -1266,9 +1266,9 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
|| opt_key == "fuzzy_skin_persistence"
|
||||
|| opt_key == "detect_overhang_wall"
|
||||
|| opt_key == "overhang_reverse"
|
||||
|| opt_key == "overhang_reverse_internal_only"
|
||||
|| opt_key == "overhang_reverse_threshold"
|
||||
|| opt_key == "wall_direction"
|
||||
|| opt_key == "alternate_internal_walls"
|
||||
|| opt_key == "enable_overhang_speed"
|
||||
|| opt_key == "detect_thin_wall"
|
||||
|| opt_key == "precise_outer_wall") {
|
||||
|
|
|
|||
|
|
@ -540,6 +540,15 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||
apply(config, &new_conf);
|
||||
is_msg_dlg_already_exist = false;
|
||||
}
|
||||
|
||||
if (config->opt_bool("alternate_internal_walls") && !config->opt_bool("staggered_inner_seams")) {
|
||||
const wxString msg_text = _(L("Reverse interanal walls should be used with Staggered inner seams option.\n Set to on."));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
dialog.ShowModal();
|
||||
new_conf.set_key_value("staggered_inner_seams", new ConfigOptionBool(true));
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManipulation::apply_null_fff_config(DynamicPrintConfig *config, std::vector<std::string> const &keys, std::map<ObjectBase *, ModelConfig *> const &configs)
|
||||
|
|
@ -889,14 +898,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
bool has_overhang_reverse = config->opt_bool("overhang_reverse");
|
||||
bool allow_overhang_reverse = !has_spiral_vase;
|
||||
toggle_line("overhang_reverse", allow_overhang_reverse);
|
||||
toggle_line("overhang_reverse_internal_only", allow_overhang_reverse && has_overhang_reverse);
|
||||
bool has_overhang_reverse_internal_only = config->opt_bool("overhang_reverse_internal_only");
|
||||
if (has_overhang_reverse_internal_only){
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
new_conf.set_key_value("overhang_reverse_threshold", new ConfigOptionFloatOrPercent(0,true));
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
toggle_line("overhang_reverse_threshold", has_detect_overhang_wall && allow_overhang_reverse && has_overhang_reverse && !has_overhang_reverse_internal_only);
|
||||
toggle_field("alternate_internal_walls", !has_spiral_vase && (config->opt_int("wall_loops") > 1));
|
||||
toggle_line("overhang_reverse_threshold", has_detect_overhang_wall && allow_overhang_reverse && has_overhang_reverse);
|
||||
toggle_line("timelapse_type", is_BBL_Printer);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2357,6 +2357,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("wall_sequence", "quality_settings_wall_and_surfaces#walls-printing-order");
|
||||
optgroup->append_single_option_line("is_infill_first", "quality_settings_wall_and_surfaces#print-infill-first");
|
||||
optgroup->append_single_option_line("wall_direction", "quality_settings_wall_and_surfaces#wall-loop-direction");
|
||||
optgroup->append_single_option_line("alternate_internal_walls", "quality_settings_wall_and_surfaces#alternate-internal-walls");
|
||||
optgroup->append_single_option_line("print_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio");
|
||||
optgroup->append_single_option_line("top_solid_infill_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio");
|
||||
optgroup->append_single_option_line("bottom_solid_infill_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio");
|
||||
|
|
@ -2401,7 +2402,6 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("make_overhang_printable_hole_size", "quality_settings_overhangs#hole-area");
|
||||
optgroup->append_single_option_line("extra_perimeters_on_overhangs", "quality_settings_overhangs#extra-perimeters-on-overhangs");
|
||||
optgroup->append_single_option_line("overhang_reverse", "quality_settings_overhangs#reverse-on-even");
|
||||
optgroup->append_single_option_line("overhang_reverse_internal_only", "quality_settings_overhangs#reverse-internal-only");
|
||||
optgroup->append_single_option_line("overhang_reverse_threshold", "quality_settings_overhangs#reverse-threshold");
|
||||
|
||||
page = add_options_page(L("Strength"), "custom-gcode_strength"); // ORCA: icon only visible on placeholders
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue