mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2026-02-15 08:59:39 -07:00
Merge branch 'main' into dev/p2s-pr
This commit is contained in:
commit
bc008ff2f0
70 changed files with 1054 additions and 666 deletions
|
|
@ -42,86 +42,6 @@ namespace Slic3r {
|
|||
//#define SUPPORT_SURFACES_OFFSET_PARAMETERS ClipperLib::jtMiter, 1.5
|
||||
#define SUPPORT_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0.
|
||||
|
||||
void remove_bridges_from_contacts(
|
||||
const PrintConfig &print_config,
|
||||
const Layer &lower_layer,
|
||||
const LayerRegion &layerm,
|
||||
float fw,
|
||||
Polygons &contact_polygons)
|
||||
{
|
||||
// compute the area of bridging perimeters
|
||||
Polygons bridges;
|
||||
{
|
||||
// Surface supporting this layer, expanded by 0.5 * nozzle_diameter, as we consider this kind of overhang to be sufficiently supported.
|
||||
Polygons lower_grown_slices = expand(lower_layer.lslices,
|
||||
//FIXME to mimic the decision in the perimeter generator, we should use half the external perimeter width.
|
||||
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm.region().config().wall_filament - 1))),
|
||||
SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
// Collect perimeters of this layer.
|
||||
//FIXME split_at_first_point() could split a bridge mid-way
|
||||
#if 0
|
||||
Polylines overhang_perimeters = layerm.perimeters.as_polylines();
|
||||
// workaround for Clipper bug, see Slic3r::Polygon::clip_as_polyline()
|
||||
for (Polyline &polyline : overhang_perimeters)
|
||||
polyline.points[0].x += 1;
|
||||
// Trim the perimeters of this layer by the lower layer to get the unsupported pieces of perimeters.
|
||||
overhang_perimeters = diff_pl(overhang_perimeters, lower_grown_slices);
|
||||
#else
|
||||
Polylines overhang_perimeters = diff_pl(layerm.perimeters.as_polylines(), lower_grown_slices);
|
||||
#endif
|
||||
|
||||
// only consider straight overhangs
|
||||
// only consider overhangs having endpoints inside layer's slices
|
||||
// convert bridging polylines into polygons by inflating them with their thickness
|
||||
// since we're dealing with bridges, we can't assume width is larger than spacing,
|
||||
// so we take the largest value and also apply safety offset to be ensure no gaps
|
||||
// are left in between
|
||||
Flow perimeter_bridge_flow = layerm.bridging_flow(frPerimeter);
|
||||
//FIXME one may want to use a maximum of bridging flow width and normal flow width, as the perimeters are calculated using the normal flow
|
||||
// and then turned to bridging flow, thus their centerlines are derived from non-bridging flow and expanding them by a bridging flow
|
||||
// may not expand them to the edge of their respective islands.
|
||||
const float w = float(0.5 * std::max(perimeter_bridge_flow.scaled_width(), perimeter_bridge_flow.scaled_spacing())) + scaled<float>(0.001);
|
||||
for (Polyline &polyline : overhang_perimeters)
|
||||
if (polyline.is_straight()) {
|
||||
// This is a bridge
|
||||
polyline.extend_start(fw);
|
||||
polyline.extend_end(fw);
|
||||
// Is the straight perimeter segment supported at both sides?
|
||||
Point pts[2] = { polyline.first_point(), polyline.last_point() };
|
||||
bool supported[2] = { false, false };
|
||||
for (size_t i = 0; i < lower_layer.lslices.size() && ! (supported[0] && supported[1]); ++ i)
|
||||
for (int j = 0; j < 2; ++ j)
|
||||
if (! supported[j] && lower_layer.lslices_bboxes[i].contains(pts[j]) && lower_layer.lslices[i].contains(pts[j]))
|
||||
supported[j] = true;
|
||||
if (supported[0] && supported[1])
|
||||
// Offset a polyline into a thick line.
|
||||
polygons_append(bridges, offset(polyline, w));
|
||||
}
|
||||
bridges = union_(bridges);
|
||||
}
|
||||
// remove the entire bridges and only support the unsupported edges
|
||||
//FIXME the brided regions are already collected as layerm.bridged. Use it?
|
||||
for (const Surface &surface : layerm.fill_surfaces.surfaces)
|
||||
if (surface.surface_type == stBottomBridge && surface.bridge_angle >= 0.0)
|
||||
polygons_append(bridges, surface.expolygon);
|
||||
//FIXME add the gap filled areas. Extrude the gaps with a bridge flow?
|
||||
// Remove the unsupported ends of the bridges from the bridged areas.
|
||||
//FIXME add supports at regular intervals to support long bridges!
|
||||
bridges = diff(bridges,
|
||||
// Offset unsupported edges into polygons.
|
||||
offset(layerm.unsupported_bridge_edges, scale_(SUPPORT_MATERIAL_MARGIN), SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||
// Remove bridged areas from the supported areas.
|
||||
contact_polygons = diff(contact_polygons, bridges, ApplySafetyOffset::Yes);
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
static int iRun = 0;
|
||||
SVG::export_expolygons(debug_out_path("support-top-contacts-remove-bridges-run%d.svg", iRun ++),
|
||||
{ { { union_ex(offset(layerm.unsupported_bridge_edges(), scale_(SUPPORT_MATERIAL_MARGIN), SUPPORT_SURFACES_OFFSET_PARAMETERS)) }, { "unsupported_bridge_edges", "orange", 0.5f } },
|
||||
{ { union_ex(contact_polygons) }, { "contact_polygons", "blue", 0.5f } },
|
||||
{ { union_ex(bridges) }, { "bridges", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
||||
#endif /* SLIC3R_DEBUG */
|
||||
}
|
||||
|
||||
// Convert some of the intermediate layers into top/bottom interface layers as well as base interface layers.
|
||||
std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interface_layers(
|
||||
const PrintObjectConfig &config,
|
||||
|
|
|
|||
|
|
@ -12,15 +12,6 @@ namespace Slic3r {
|
|||
class PrintObject;
|
||||
class SupportLayer;
|
||||
|
||||
// Remove bridges from support contact areas.
|
||||
// To be called if PrintObjectConfig::dont_support_bridges.
|
||||
void remove_bridges_from_contacts(
|
||||
const PrintConfig &print_config,
|
||||
const Layer &lower_layer,
|
||||
const LayerRegion &layerm,
|
||||
float fw,
|
||||
Polygons &contact_polygons);
|
||||
|
||||
// Turn some of the base layers into base interface layers.
|
||||
// For soluble interfaces with non-soluble bases, print maximum two first interface layers with the base
|
||||
// extruder to improve adhesion of the soluble filament to the base.
|
||||
|
|
|
|||
|
|
@ -1390,7 +1390,6 @@ static inline ExPolygons detect_overhangs(
|
|||
double thresh_angle = object_config.support_threshold_angle.value > 0 ? object_config.support_threshold_angle.value + 1 : 0;
|
||||
thresh_angle = std::min(thresh_angle, 89.); // BBS should be smaller than 90
|
||||
const double threshold_rad = Geometry::deg2rad(thresh_angle);
|
||||
const coordf_t max_bridge_length = scale_(object_config.max_bridge_length.value);
|
||||
const bool bridge_no_support = object_config.bridge_no_support.value;
|
||||
const coordf_t xy_expansion = scale_(object_config.support_expansion.value);
|
||||
float lower_layer_offset = 0;
|
||||
|
|
|
|||
|
|
@ -188,7 +188,6 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
[[nodiscard]] static const std::vector<Polygons> generate_overhangs(const TreeSupportSettings &settings, PrintObject &print_object, std::function<void()> throw_on_cancel)
|
||||
{
|
||||
|
|
@ -262,11 +261,11 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
|
|||
}
|
||||
if (! (enforced_layer || blockers_layers.empty() || blockers_layers[layer_id].empty()))
|
||||
overhangs = diff(overhangs, offset_ex(union_(blockers_layers[layer_id]), scale_(radius_sample_resolution)), ApplySafetyOffset::Yes);
|
||||
if (config.bridge_no_support) {
|
||||
for (const LayerRegion *layerm : current_layer.regions())
|
||||
remove_bridges_from_contacts(print_config, lower_layer, *layerm,
|
||||
float(layerm->flow(frExternalPerimeter).scaled_width()), overhangs);
|
||||
}
|
||||
//if (config.bridge_no_support) {
|
||||
// for (const LayerRegion *layerm : current_layer.regions())
|
||||
// remove_bridges_from_contacts(print_config, lower_layer, *layerm,
|
||||
// float(layerm->flow(frExternalPerimeter).scaled_width()), overhangs);
|
||||
//}
|
||||
}
|
||||
//check_self_intersections(overhangs, "generate_overhangs1");
|
||||
if (! enforcers_layers.empty() && ! enforcers_layers[layer_id].empty()) {
|
||||
|
|
@ -331,6 +330,7 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
|
|||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief Precalculates all avoidances, that could be required.
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ void BedShapePanel::build_panel(const Pointfs& default_pt, const std::string& cu
|
|||
Line line{ "", "" };
|
||||
line.full_width = 1;
|
||||
line.widget = [this](wxWindow* parent) {
|
||||
Button* shape_btn = new Button(parent, _L("Load shape from STL..."));
|
||||
Button* shape_btn = new Button(parent, _L("Load shape from STL ..."));
|
||||
shape_btn->SetStyle(ButtonStyle::Regular, ButtonType::Expanded);
|
||||
|
||||
wxSizer* shape_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
|
|
|||
|
|
@ -754,9 +754,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
toggle_line(el, support_is_organic);
|
||||
|
||||
toggle_field("tree_support_brim_width", support_is_tree && !config->opt_bool("tree_support_auto_brim"));
|
||||
// non-organic tree support use max_bridge_length instead of bridge_no_support
|
||||
toggle_line("max_bridge_length", support_is_normal_tree);
|
||||
toggle_line("bridge_no_support", !support_is_normal_tree);
|
||||
// tree support use max_bridge_length instead of bridge_no_support
|
||||
toggle_line("max_bridge_length", support_is_tree);
|
||||
toggle_line("bridge_no_support", !support_is_tree);
|
||||
toggle_line("support_critical_regions_only", is_auto(support_type) && support_is_tree);
|
||||
|
||||
for (auto el : { "support_interface_filament",
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ void uiAmsPercentHumidityDryPopup::UpdateContents()
|
|||
// table grid
|
||||
const wxString& humidity_str = wxString::Format("%d%%", m_humidity_percent);
|
||||
m_humidity_label->SetLabel(humidity_str);
|
||||
const wxString& temp_str = wxString::Format(_L("%d \u2103"), (int)std::round(m_current_temperature));
|
||||
const wxString& temp_str = wxString::Format(u8"%d\u2103" /* °C */, (int)std::round(m_current_temperature));
|
||||
m_temperature_label->SetLabel(temp_str);
|
||||
|
||||
if (m_left_dry_time > 0)
|
||||
|
|
|
|||
|
|
@ -864,14 +864,14 @@ void MenuFactory::append_menu_item_reload_from_disk(wxMenu* menu)
|
|||
|
||||
void MenuFactory::append_menu_item_replace_with_stl(wxMenu *menu)
|
||||
{
|
||||
append_menu_item(menu, wxID_ANY, _L("Replace with STL"), _L("Replace the selected part with new STL"),
|
||||
append_menu_item(menu, wxID_ANY, _L("Replace with STL") + dots, _L("Replace the selected part with new STL."),
|
||||
[](wxCommandEvent &) { plater()->replace_with_stl(); }, "", menu,
|
||||
[]() { return plater()->can_replace_with_stl(); }, m_parent);
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_replace_all_with_stl(wxMenu *menu)
|
||||
{
|
||||
append_menu_item(menu, wxID_ANY, _L("Replace all with STL"), _L("Replace all selected parts with STL from folder"),
|
||||
append_menu_item(menu, wxID_ANY, _L("Replace all with STL") + dots, _L("Replace all selected parts with STL from folder."),
|
||||
[](wxCommandEvent &) { plater()->replace_all_with_stl(); }, "", menu,
|
||||
[]() { return plater()->can_replace_all_with_stl(); }, m_parent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1186,8 +1186,8 @@ void IMSlider::render_input_custom_gcode(std::string custom_gcode)
|
|||
strcpy(m_custom_gcode, custom_gcode.c_str());
|
||||
}
|
||||
const int text_height = 6;
|
||||
const ImGuiInputTextFlags flag = ImGuiInputTextFlags_Multiline;
|
||||
ImGui::InputTextMultiline("##text", m_custom_gcode, sizeof(m_custom_gcode), ImVec2(-1, ImGui::GetTextLineHeight() * text_height), flag);
|
||||
|
||||
ImGui::InputTextMultiline("##text", m_custom_gcode, sizeof(m_custom_gcode), ImVec2(-1, ImGui::GetTextLineHeight() * text_height));
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::SameLine(ImGui::GetStyle().WindowPadding.x * 14);
|
||||
|
|
|
|||
|
|
@ -1029,7 +1029,7 @@ wxBoxSizer *ObjColorPanel::create_color_icon_map_rgba_sizer(wxWindow *parent, in
|
|||
icon_sizer->Add(icon, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0); // wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
|
||||
icon_sizer->AddSpacer(FromDIP(10));
|
||||
|
||||
wxStaticText *map_text = new wxStaticText(parent, wxID_ANY, _L("—> "));
|
||||
wxStaticText *map_text = new wxStaticText(parent, wxID_ANY, u8"—> ");
|
||||
map_text->SetFont(Label::Head_12);
|
||||
icon_sizer->Add(map_text, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ PartSkipDialog::PartSkipDialog(wxWindow *parent) : DPIDialog(parent, wxID_ANY, _
|
|||
m_zoom_out_btn->SetCornerRadius(0);
|
||||
m_zoom_out_btn->SetMinSize(wxSize(FromDIP(56), FromDIP(28)));
|
||||
|
||||
m_percent_label = new Button(m_book_third_panel, _L("100 %"));
|
||||
m_percent_label = new Button(m_book_third_panel, "100%");
|
||||
m_percent_label->SetBackgroundColor(percent_bg);
|
||||
m_percent_label->SetBorderColor(wxColour(238, 238, 238));
|
||||
m_percent_label->SetMinSize(wxSize(FromDIP(56), FromDIP(28)));
|
||||
|
|
@ -664,7 +664,7 @@ void PartSkipDialog::UpdatePartsStateFromCanvas(wxCommandEvent &event)
|
|||
UpdateDialogUI();
|
||||
}
|
||||
|
||||
void PartSkipDialog::UpdateZoomPercent() { m_percent_label->SetLabel(wxString::Format(_L("%d%%"), m_zoom_percent)); }
|
||||
void PartSkipDialog::UpdateZoomPercent() { m_percent_label->SetLabel(wxString::Format("%d%%", m_zoom_percent)); }
|
||||
|
||||
void PartSkipDialog::UpdateCountLabel()
|
||||
{
|
||||
|
|
@ -674,7 +674,7 @@ void PartSkipDialog::UpdateCountLabel()
|
|||
if (part_state == PartState::psChecked) check_cnt++;
|
||||
if (part_state != PartState::psSkipped) tot_cnt++;
|
||||
}
|
||||
m_cnt_label->SetLabel(wxString::Format(_L("%d"), check_cnt));
|
||||
m_cnt_label->SetLabel(wxString::Format("%d", check_cnt));
|
||||
m_cnt_label->Fit();
|
||||
m_tot_label->SetLabel(wxString::Format(_L("/%d Selected"), tot_cnt));
|
||||
m_tot_label->Fit();
|
||||
|
|
|
|||
|
|
@ -3866,7 +3866,7 @@ void StatusPanel::update_partskip_subtask(MachineObject *obj){
|
|||
BOOST_LOG_TRIVIAL(info) << "part skip: recv printer normal data.";
|
||||
}
|
||||
if (part_cnt > 0)
|
||||
partskip_button->SetLabel(wxString::Format(_L("(%d)"), part_cnt));
|
||||
partskip_button->SetLabel(wxString::Format("(%d)", part_cnt));
|
||||
else
|
||||
partskip_button->SetLabel("");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue