mirror of
https://git.mirrors.martin98.com/https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-28 16:32:02 +08:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
commit
7da1622e76
1
deps/deps-linux.cmake
vendored
1
deps/deps-linux.cmake
vendored
@ -80,7 +80,6 @@ ExternalProject_Add(dep_libcurl
|
|||||||
--disable-smb
|
--disable-smb
|
||||||
--disable-smtp
|
--disable-smtp
|
||||||
--disable-gopher
|
--disable-gopher
|
||||||
--disable-crypto-auth
|
|
||||||
--without-gssapi
|
--without-gssapi
|
||||||
--without-libpsl
|
--without-libpsl
|
||||||
--without-libidn2
|
--without-libidn2
|
||||||
|
1
deps/deps-macos.cmake
vendored
1
deps/deps-macos.cmake
vendored
@ -67,7 +67,6 @@ ExternalProject_Add(dep_libcurl
|
|||||||
--disable-smb
|
--disable-smb
|
||||||
--disable-smtp
|
--disable-smtp
|
||||||
--disable-gopher
|
--disable-gopher
|
||||||
--disable-crypto-auth
|
|
||||||
--without-gssapi
|
--without-gssapi
|
||||||
--without-libpsl
|
--without-libpsl
|
||||||
--without-libidn2
|
--without-libidn2
|
||||||
|
@ -910,12 +910,16 @@ void mark_boundary_segments_touching_infill(
|
|||||||
const std::vector<float> &contour_parameters = boundary_parameters[it_contour_and_segment->first];
|
const std::vector<float> &contour_parameters = boundary_parameters[it_contour_and_segment->first];
|
||||||
const float contour_length = contour_parameters.back();
|
const float contour_length = contour_parameters.back();
|
||||||
const float param_seg_pt1 = contour_parameters[it_contour_and_segment->second];
|
const float param_seg_pt1 = contour_parameters[it_contour_and_segment->second];
|
||||||
|
const float param_seg_pt2 = contour_parameters[it_contour_and_segment->second + 1];
|
||||||
#ifdef INFILL_DEBUG_OUTPUT
|
#ifdef INFILL_DEBUG_OUTPUT
|
||||||
this->perimeter_overlaps.push_back({ Point((seg_pt1 + (seg_pt2 - seg_pt1).normalized() * interval.first).cast<coord_t>()),
|
this->perimeter_overlaps.push_back({ Point((seg_pt1 + (seg_pt2 - seg_pt1).normalized() * interval.first).cast<coord_t>()),
|
||||||
Point((seg_pt1 + (seg_pt2 - seg_pt1).normalized() * interval.second).cast<coord_t>()) });
|
Point((seg_pt1 + (seg_pt2 - seg_pt1).normalized() * interval.second).cast<coord_t>()) });
|
||||||
#endif // INFILL_DEBUG_OUTPUT
|
#endif // INFILL_DEBUG_OUTPUT
|
||||||
const float param_overlap1 = param_seg_pt1 + interval.first;
|
assert(interval.first >= 0.);
|
||||||
const float param_overlap2 = param_seg_pt1 + interval.second;
|
assert(interval.second >= 0.);
|
||||||
|
assert(interval.first <= interval.second);
|
||||||
|
const auto param_overlap1 = std::min(param_seg_pt2, float(param_seg_pt1 + interval.first));
|
||||||
|
const auto param_overlap2 = std::min(param_seg_pt2, float(param_seg_pt1 + interval.second));
|
||||||
// 2) Find the ContourIntersectionPoints before param_overlap1 and after param_overlap2.
|
// 2) Find the ContourIntersectionPoints before param_overlap1 and after param_overlap2.
|
||||||
// Find the span of ContourIntersectionPoints, that is trimmed by the interval (param_overlap1, param_overlap2).
|
// Find the span of ContourIntersectionPoints, that is trimmed by the interval (param_overlap1, param_overlap2).
|
||||||
ContourIntersectionPoint *ip_low, *ip_high;
|
ContourIntersectionPoint *ip_low, *ip_high;
|
||||||
|
@ -182,12 +182,14 @@ void FillGyroid::_fill_surface_single(
|
|||||||
|
|
||||||
polylines = intersection_pl(polylines, to_polygons(expolygon));
|
polylines = intersection_pl(polylines, to_polygons(expolygon));
|
||||||
|
|
||||||
if (! polylines.empty())
|
if (! polylines.empty()) {
|
||||||
// remove too small bits (larger than longer)
|
// Remove very small bits, but be careful to not remove infill lines connecting thin walls!
|
||||||
|
// The infill perimeter lines should be separated by around a single infill line width.
|
||||||
|
const double minlength = scale_(0.8 * this->spacing);
|
||||||
polylines.erase(
|
polylines.erase(
|
||||||
//FIXME what is the small size? Removing tiny extrusions disconnects walls!
|
std::remove_if(polylines.begin(), polylines.end(), [minlength](const Polyline &pl) { return pl.length() < minlength; }),
|
||||||
std::remove_if(polylines.begin(), polylines.end(), [this](const Polyline &pl) { return pl.length() < scale_(this->spacing * 3); }),
|
|
||||||
polylines.end());
|
polylines.end());
|
||||||
|
}
|
||||||
|
|
||||||
if (! polylines.empty()) {
|
if (! polylines.empty()) {
|
||||||
// connect lines
|
// connect lines
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "FillRectilinear.hpp"
|
#include "FillRectilinear.hpp"
|
||||||
|
|
||||||
// #define SLIC3R_DEBUG
|
// #define SLIC3R_DEBUG
|
||||||
|
// #define INFILL_DEBUG_OUTPUT
|
||||||
|
|
||||||
// Make assert active if SLIC3R_DEBUG
|
// Make assert active if SLIC3R_DEBUG
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
@ -26,6 +27,10 @@
|
|||||||
#include "SVG.hpp"
|
#include "SVG.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SLIC3R_DEBUG) || defined(INFILL_DEBUG_OUTPUT)
|
||||||
|
#include "SVG.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// We want our version of assert.
|
// We want our version of assert.
|
||||||
@ -1870,6 +1875,60 @@ static std::vector<MonotonicRegion> generate_montonous_regions(std::vector<Segme
|
|||||||
return monotonic_regions;
|
return monotonic_regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef INFILL_DEBUG_OUTPUT
|
||||||
|
static void export_monotonous_regions_to_svg(
|
||||||
|
const ExPolygonWithOffset &poly_with_offset,
|
||||||
|
const std::vector<SegmentedIntersectionLine> &segs,
|
||||||
|
const std::vector<MonotonicRegion> &monotonic_regions,
|
||||||
|
const std::string &path)
|
||||||
|
{
|
||||||
|
BoundingBox bbox = get_extents(poly_with_offset.polygons_src);
|
||||||
|
bbox.offset(scale_(3.));
|
||||||
|
|
||||||
|
::Slic3r::SVG svg(path, bbox);
|
||||||
|
svg.draw(poly_with_offset.polygons_src);
|
||||||
|
svg.draw_outline(poly_with_offset.polygons_src, "green");
|
||||||
|
svg.draw_outline(poly_with_offset.polygons_outer, "green");
|
||||||
|
svg.draw_outline(poly_with_offset.polygons_inner, "green");
|
||||||
|
|
||||||
|
// Draw the infill line candidates in red.
|
||||||
|
for (const SegmentedIntersectionLine &sil : segs) {
|
||||||
|
for (size_t i = 0; i + 1 < sil.intersections.size(); ++ i)
|
||||||
|
if (sil.intersections[i].type == SegmentIntersection::INNER_LOW && sil.intersections[i + 1].type == SegmentIntersection::INNER_HIGH) {
|
||||||
|
Line l(Point(sil.pos, sil.intersections[i].pos()), Point(sil.pos, sil.intersections[i + 1].pos()));
|
||||||
|
svg.draw(l, "blue");
|
||||||
|
} else if (sil.intersections[i].type == SegmentIntersection::INNER_HIGH && sil.intersections[i].has_vertical_up()) {
|
||||||
|
std::string color;
|
||||||
|
const SegmentIntersection *it = &sil.intersections[i];
|
||||||
|
switch (it->vertical_up_quality()) {
|
||||||
|
case SegmentIntersection::LinkQuality::Invalid: color = "red"; break;
|
||||||
|
case SegmentIntersection::LinkQuality::Valid: color = "blue"; break;
|
||||||
|
case SegmentIntersection::LinkQuality::TooLong:
|
||||||
|
default: color = "yellow"; break;
|
||||||
|
}
|
||||||
|
Polyline polyline;
|
||||||
|
polyline.points.push_back({ sil.pos, it->pos() });
|
||||||
|
emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, &sil - segs.data() , it->iContour, it - sil.intersections.data(), it->vertical_up(), polyline, it->has_left_vertical_up());
|
||||||
|
svg.draw(polyline, color, scale_(0.05));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the monotonic regions.
|
||||||
|
for (const MonotonicRegion ®ion : monotonic_regions) {
|
||||||
|
auto draw_boundary_line = [&poly_with_offset, &segs, &svg](const MonotonicRegion::Boundary &boundary) {
|
||||||
|
const SegmentedIntersectionLine &sil = segs[boundary.vline];
|
||||||
|
for (size_t i = boundary.low; i < boundary.high; ++ i)
|
||||||
|
if (sil.intersections[i].type == SegmentIntersection::INNER_LOW && sil.intersections[i + 1].type == SegmentIntersection::INNER_HIGH) {
|
||||||
|
Line l(Point(sil.pos, sil.intersections[i].pos()), Point(sil.pos, sil.intersections[i + 1].pos()));
|
||||||
|
svg.draw(l, "red", scale_(0.05));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
draw_boundary_line(region.left);
|
||||||
|
draw_boundary_line(region.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // INFILL_DEBUG_OUTPUT
|
||||||
|
|
||||||
// Traverse path, calculate length of the draw for the purpose of optimization.
|
// Traverse path, calculate length of the draw for the purpose of optimization.
|
||||||
// This function is very similar to polylines_from_paths() in the way how it traverses the path, but
|
// This function is very similar to polylines_from_paths() in the way how it traverses the path, but
|
||||||
// polylines_from_paths() emits a path, while this function just calculates the path length.
|
// polylines_from_paths() emits a path, while this function just calculates the path length.
|
||||||
@ -1928,14 +1987,22 @@ static float montonous_region_path_length(const MonotonicRegion ®ion, bool di
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
int inext = it->right_horizontal();
|
int inext = it->right_horizontal();
|
||||||
if (inext != -1 && it->next_on_contour_quality == SegmentIntersection::LinkQuality::Valid) {
|
assert(iright != -1);
|
||||||
|
assert(inext == -1 || inext == iright);
|
||||||
|
|
||||||
|
// Find the end of the next overlapping vertical segment.
|
||||||
|
const SegmentedIntersectionLine &vline_right = segs[i_vline + 1];
|
||||||
|
const SegmentIntersection *right = going_up ?
|
||||||
|
&vertical_run_top(vline_right, vline_right.intersections[iright]) : &vertical_run_bottom(vline_right, vline_right.intersections[iright]);
|
||||||
|
i_intersection = int(right - vline_right.intersections.data());
|
||||||
|
|
||||||
|
if (inext == i_intersection && it->next_on_contour_quality == SegmentIntersection::LinkQuality::Valid) {
|
||||||
// Summarize length of the connection line along the perimeter.
|
// Summarize length of the connection line along the perimeter.
|
||||||
//FIXME should it be weighted with a lower weight than non-extruding connection line? What weight?
|
//FIXME should it be weighted with a lower weight than non-extruding connection line? What weight?
|
||||||
// Taking half of the length.
|
// Taking half of the length.
|
||||||
total_length += 0.5f * float(measure_perimeter_horizontal_segment_length(poly_with_offset, segs, i_vline, it - vline.intersections.data(), inext));
|
total_length += 0.5f * float(measure_perimeter_horizontal_segment_length(poly_with_offset, segs, i_vline, it - vline.intersections.data(), inext));
|
||||||
// Don't add distance to the next vertical line start to the total length.
|
// Don't add distance to the next vertical line start to the total length.
|
||||||
no_perimeter = false;
|
no_perimeter = false;
|
||||||
i_intersection = inext;
|
|
||||||
} else {
|
} else {
|
||||||
// Finish the current vertical line,
|
// Finish the current vertical line,
|
||||||
going_up ? ++ it : -- it;
|
going_up ? ++ it : -- it;
|
||||||
@ -1945,14 +2012,6 @@ static float montonous_region_path_length(const MonotonicRegion ®ion, bool di
|
|||||||
last_point = Vec2f(vline.pos, it->pos());
|
last_point = Vec2f(vline.pos, it->pos());
|
||||||
// Remember to add distance to the last point.
|
// Remember to add distance to the last point.
|
||||||
no_perimeter = true;
|
no_perimeter = true;
|
||||||
if (inext == -1) {
|
|
||||||
// Find the end of the next overlapping vertical segment.
|
|
||||||
const SegmentedIntersectionLine &vline_right = segs[i_vline + 1];
|
|
||||||
const SegmentIntersection *right = going_up ?
|
|
||||||
&vertical_run_top(vline_right, vline_right.intersections[iright]) : &vertical_run_bottom(vline_right, vline_right.intersections[iright]);
|
|
||||||
i_intersection = int(right - vline_right.intersections.data());
|
|
||||||
} else
|
|
||||||
i_intersection = inext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++ i_vline;
|
++ i_vline;
|
||||||
@ -2580,10 +2639,18 @@ static void polylines_from_paths(const std::vector<MonotonicRegionLink> &path, c
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
int inext = it->right_horizontal();
|
int inext = it->right_horizontal();
|
||||||
if (inext != -1 && it->next_on_contour_quality == SegmentIntersection::LinkQuality::Valid) {
|
assert(iright != -1);
|
||||||
|
assert(inext == -1 || inext == iright);
|
||||||
|
|
||||||
|
// Find the end of the next overlapping vertical segment.
|
||||||
|
const SegmentedIntersectionLine &vline_right = segs[i_vline + 1];
|
||||||
|
const SegmentIntersection *right = going_up ?
|
||||||
|
&vertical_run_top(vline_right, vline_right.intersections[iright]) : &vertical_run_bottom(vline_right, vline_right.intersections[iright]);
|
||||||
|
i_intersection = int(right - vline_right.intersections.data());
|
||||||
|
|
||||||
|
if (inext == i_intersection && it->next_on_contour_quality == SegmentIntersection::LinkQuality::Valid) {
|
||||||
// Emit a horizontal connection contour.
|
// Emit a horizontal connection contour.
|
||||||
emit_perimeter_prev_next_segment(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, true);
|
emit_perimeter_prev_next_segment(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, true);
|
||||||
i_intersection = inext;
|
|
||||||
} else {
|
} else {
|
||||||
// Finish the current vertical line,
|
// Finish the current vertical line,
|
||||||
going_up ? ++ it : -- it;
|
going_up ? ++ it : -- it;
|
||||||
@ -2591,14 +2658,6 @@ static void polylines_from_paths(const std::vector<MonotonicRegionLink> &path, c
|
|||||||
assert(it->is_high() == going_up);
|
assert(it->is_high() == going_up);
|
||||||
polyline->points.back() = Point(vline.pos, it->pos());
|
polyline->points.back() = Point(vline.pos, it->pos());
|
||||||
finish_polyline();
|
finish_polyline();
|
||||||
if (inext == -1) {
|
|
||||||
// Find the end of the next overlapping vertical segment.
|
|
||||||
const SegmentedIntersectionLine &vline_right = segs[i_vline + 1];
|
|
||||||
const SegmentIntersection *right = going_up ?
|
|
||||||
&vertical_run_top(vline_right, vline_right.intersections[iright]) : &vertical_run_bottom(vline_right, vline_right.intersections[iright]);
|
|
||||||
i_intersection = int(right - vline_right.intersections.data());
|
|
||||||
} else
|
|
||||||
i_intersection = inext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++ i_vline;
|
++ i_vline;
|
||||||
@ -2717,6 +2776,12 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa
|
|||||||
// Insert phony OUTER_HIGH / OUTER_LOW pairs at the position where the contour is pinched.
|
// Insert phony OUTER_HIGH / OUTER_LOW pairs at the position where the contour is pinched.
|
||||||
pinch_contours_insert_phony_outer_intersections(segs);
|
pinch_contours_insert_phony_outer_intersections(segs);
|
||||||
std::vector<MonotonicRegion> regions = generate_montonous_regions(segs);
|
std::vector<MonotonicRegion> regions = generate_montonous_regions(segs);
|
||||||
|
#ifdef INFILL_DEBUG_OUTPUT
|
||||||
|
{
|
||||||
|
static int iRun;
|
||||||
|
export_monotonous_regions_to_svg(poly_with_offset, segs, regions, debug_out_path("%s-%03d.svg", "MontonousRegions-initial", iRun ++));
|
||||||
|
}
|
||||||
|
#endif // INFILL_DEBUG_OUTPUT
|
||||||
connect_monotonic_regions(regions, poly_with_offset, segs);
|
connect_monotonic_regions(regions, poly_with_offset, segs);
|
||||||
if (! regions.empty()) {
|
if (! regions.empty()) {
|
||||||
std::mt19937_64 rng;
|
std::mt19937_64 rng;
|
||||||
|
@ -861,9 +861,15 @@ void Choice::BUILD() {
|
|||||||
temp->SetItemBitmap(0, empty_bmp);
|
temp->SetItemBitmap(0, empty_bmp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), temp->GetId());
|
|
||||||
temp->Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent&) { m_is_dropped = true; });
|
temp->Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent&) { m_is_dropped = true; });
|
||||||
temp->Bind(wxEVT_COMBOBOX_CLOSEUP, [this](wxCommandEvent&) { m_is_dropped = false; });
|
temp->Bind(wxEVT_COMBOBOX_CLOSEUP, [this, temp](wxCommandEvent&) {
|
||||||
|
// EVT_COMBOBOX_CLOSEUP is called after EVT_COMBOBOX on Windows
|
||||||
|
// so, always set m_suppress_change to "true"
|
||||||
|
#ifndef __WXMSW__
|
||||||
|
if (m_last_selected == temp->GetSelection())
|
||||||
|
#endif //__WXMSW__
|
||||||
|
m_is_dropped = false;
|
||||||
|
});
|
||||||
|
|
||||||
temp->Bind(wxEVT_COMBOBOX, ([this, temp](wxCommandEvent evt) {
|
temp->Bind(wxEVT_COMBOBOX, ([this, temp](wxCommandEvent evt) {
|
||||||
if (m_suppress_scroll) {
|
if (m_suppress_scroll) {
|
||||||
@ -874,6 +880,7 @@ void Choice::BUILD() {
|
|||||||
m_last_selected = evt.GetSelection();
|
m_last_selected = evt.GetSelection();
|
||||||
}
|
}
|
||||||
on_change_field();
|
on_change_field();
|
||||||
|
m_is_dropped = false;
|
||||||
}), temp->GetId());
|
}), temp->GetId());
|
||||||
|
|
||||||
if (m_is_editable) {
|
if (m_is_editable) {
|
||||||
@ -998,13 +1005,14 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
|||||||
else
|
else
|
||||||
text_value = boost::any_cast<wxString>(value);
|
text_value = boost::any_cast<wxString>(value);
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
for (auto el : m_opt.enum_values)
|
const std::vector<std::string>& enums = m_opt.enum_values.empty() ? m_opt.enum_labels : m_opt.enum_values;
|
||||||
|
for (auto el : enums)
|
||||||
{
|
{
|
||||||
if (el == text_value)
|
if (el == text_value)
|
||||||
break;
|
break;
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
if (idx == m_opt.enum_values.size()) {
|
if (idx == enums.size()) {
|
||||||
// For editable Combobox under OSX is needed to set selection to -1 explicitly,
|
// For editable Combobox under OSX is needed to set selection to -1 explicitly,
|
||||||
// otherwise selection doesn't be changed
|
// otherwise selection doesn't be changed
|
||||||
field->SetSelection(-1);
|
field->SetSelection(-1);
|
||||||
@ -1012,7 +1020,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
field->SetSelection(idx);
|
field->SetSelection(idx);
|
||||||
if (m_suppress_scroll && idx < m_opt.enum_values.size()) m_last_selected = idx;
|
if (m_suppress_scroll && idx < enums.size()) m_last_selected = idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case coEnum: {
|
case coEnum: {
|
||||||
|
@ -189,10 +189,10 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent, wxString printer_
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_printer = *printer;
|
||||||
const std::set<std::string>& preset_names = printer->get_preset_names();
|
const std::set<std::string>& preset_names = printer->get_preset_names();
|
||||||
for (const std::string& preset_name : preset_names)
|
for (const std::string& preset_name : preset_names)
|
||||||
m_presets.emplace_back(new PresetForPrinter(this, preset_name));
|
m_presets.emplace_back(new PresetForPrinter(this, preset_name));
|
||||||
m_printer = *printer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_presets.size() == 1)
|
if (m_presets.size() == 1)
|
||||||
|
@ -513,6 +513,10 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
|
|||||||
m_og_sla->append_line(line);
|
m_og_sla->append_line(line);
|
||||||
|
|
||||||
m_og_sla->activate();
|
m_og_sla->activate();
|
||||||
|
choice = dynamic_cast<Choice*>(m_og_sla->get_field("support"));
|
||||||
|
choice->suppress_scroll();
|
||||||
|
choice = dynamic_cast<Choice*>(m_og_sla->get_field("pad"));
|
||||||
|
choice->suppress_scroll();
|
||||||
|
|
||||||
m_sizer = new wxBoxSizer(wxVERTICAL);
|
m_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
m_sizer->Add(m_og->sizer, 0, wxEXPAND);
|
m_sizer->Add(m_og->sizer, 0, wxEXPAND);
|
||||||
|
@ -103,8 +103,15 @@ PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const
|
|||||||
|
|
||||||
// parameters for an icon's drawing
|
// parameters for an icon's drawing
|
||||||
fill_width_height();
|
fill_width_height();
|
||||||
Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent& evt) { m_suppress_change = false; });
|
Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent&) { m_suppress_change = false; });
|
||||||
Bind(wxEVT_COMBOBOX_CLOSEUP, [this](wxCommandEvent& evt) { m_suppress_change = true ; });
|
Bind(wxEVT_COMBOBOX_CLOSEUP, [this](wxCommandEvent&) {
|
||||||
|
// EVT_COMBOBOX_CLOSEUP is called after EVT_COMBOBOX on Windows
|
||||||
|
// so, always set m_suppress_change to "true"
|
||||||
|
#ifndef __WXMSW__
|
||||||
|
if (m_last_selected == this->GetSelection())
|
||||||
|
#endif //__WXMSW__
|
||||||
|
m_suppress_change = true;
|
||||||
|
});
|
||||||
|
|
||||||
Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
|
Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
|
||||||
// see https://github.com/prusa3d/PrusaSlicer/issues/3889
|
// see https://github.com/prusa3d/PrusaSlicer/issues/3889
|
||||||
@ -572,6 +579,7 @@ PlaterPresetComboBox::PlaterPresetComboBox(wxWindow *parent, Preset::Type preset
|
|||||||
} else {
|
} else {
|
||||||
evt.StopPropagation();
|
evt.StopPropagation();
|
||||||
}
|
}
|
||||||
|
m_suppress_change = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (m_type == Preset::TYPE_FILAMENT)
|
if (m_type == Preset::TYPE_FILAMENT)
|
||||||
@ -911,6 +919,7 @@ TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
evt.StopPropagation();
|
evt.StopPropagation();
|
||||||
|
m_suppress_change = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,6 +448,15 @@ Http& Http::auth_digest(const std::string &user, const std::string &password)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Http& Http::auth_basic(const std::string &user, const std::string &password)
|
||||||
|
{
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_USERNAME, user.c_str());
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_PASSWORD, password.c_str());
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Http& Http::ca_file(const std::string &name)
|
Http& Http::ca_file(const std::string &name)
|
||||||
{
|
{
|
||||||
if (p && priv::ca_file_supported(p->curl)) {
|
if (p && priv::ca_file_supported(p->curl)) {
|
||||||
|
@ -67,6 +67,8 @@ public:
|
|||||||
Http& remove_header(std::string name);
|
Http& remove_header(std::string name);
|
||||||
// Authorization by HTTP digest, based on RFC2617.
|
// Authorization by HTTP digest, based on RFC2617.
|
||||||
Http& auth_digest(const std::string &user, const std::string &password);
|
Http& auth_digest(const std::string &user, const std::string &password);
|
||||||
|
// Basic HTTP authorization
|
||||||
|
Http& auth_basic(const std::string &user, const std::string &password);
|
||||||
// Sets a CA certificate file for usage with HTTPS. This is only supported on some backends,
|
// Sets a CA certificate file for usage with HTTPS. This is only supported on some backends,
|
||||||
// specifically, this is supported with OpenSSL and NOT supported with Windows and OS X native certificate store.
|
// specifically, this is supported with OpenSSL and NOT supported with Windows and OS X native certificate store.
|
||||||
// See also ca_file_supported().
|
// See also ca_file_supported().
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "slic3r/Utils/Http.hpp"
|
#include "slic3r/Utils/Http.hpp"
|
||||||
|
|
||||||
TEST_CASE("Http", "[Http][NotWorking]") {
|
TEST_CASE("Check SSL certificates paths", "[Http][NotWorking]") {
|
||||||
|
|
||||||
Slic3r::Http g = Slic3r::Http::get("https://github.com/");
|
Slic3r::Http g = Slic3r::Http::get("https://github.com/");
|
||||||
|
|
||||||
@ -20,3 +20,41 @@ TEST_CASE("Http", "[Http][NotWorking]") {
|
|||||||
REQUIRE(status == 200);
|
REQUIRE(status == 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Http digest authentication", "[Http][NotWorking]") {
|
||||||
|
Slic3r::Http g = Slic3r::Http::get("https://jigsaw.w3.org/HTTP/Digest/");
|
||||||
|
|
||||||
|
g.auth_digest("guest", "guest");
|
||||||
|
|
||||||
|
unsigned status = 0;
|
||||||
|
g.on_error([&status](std::string, std::string, unsigned http_status) {
|
||||||
|
status = http_status;
|
||||||
|
});
|
||||||
|
|
||||||
|
g.on_complete([&status](std::string /* body */, unsigned http_status){
|
||||||
|
status = http_status;
|
||||||
|
});
|
||||||
|
|
||||||
|
g.perform_sync();
|
||||||
|
|
||||||
|
REQUIRE(status == 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Http basic authentication", "[Http][NotWorking]") {
|
||||||
|
Slic3r::Http g = Slic3r::Http::get("https://jigsaw.w3.org/HTTP/Basic/");
|
||||||
|
|
||||||
|
g.auth_basic("guest", "guest");
|
||||||
|
|
||||||
|
unsigned status = 0;
|
||||||
|
g.on_error([&status](std::string, std::string, unsigned http_status) {
|
||||||
|
status = http_status;
|
||||||
|
});
|
||||||
|
|
||||||
|
g.on_complete([&status](std::string /* body */, unsigned http_status){
|
||||||
|
status = http_status;
|
||||||
|
});
|
||||||
|
|
||||||
|
g.perform_sync();
|
||||||
|
|
||||||
|
REQUIRE(status == 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user