Merge branch 'master' into dk_connect

This commit is contained in:
Lukas Matena 2024-05-21 08:27:06 +02:00
commit 75f13002ff
12 changed files with 144 additions and 37 deletions

View File

@ -115,6 +115,19 @@ struct OverhangAttributes {
float proximity_to_curled_lines; //value between 0 and 1
};
inline bool operator==(const OverhangAttributes &lhs, const OverhangAttributes &rhs) {
if (std::abs(lhs.start_distance_from_prev_layer - rhs.start_distance_from_prev_layer) > std::numeric_limits<float>::epsilon()) {
return false;
}
if (std::abs(lhs.end_distance_from_prev_layer - rhs.end_distance_from_prev_layer) > std::numeric_limits<float>::epsilon()) {
return false;
}
if (std::abs(lhs.proximity_to_curled_lines - rhs.proximity_to_curled_lines) > std::numeric_limits<float>::epsilon()) {
return false;
}
return true;
}
struct ExtrusionAttributes : ExtrusionFlow
{
ExtrusionAttributes() = default;
@ -132,7 +145,7 @@ struct ExtrusionAttributes : ExtrusionFlow
inline bool operator==(const ExtrusionAttributes &lhs, const ExtrusionAttributes &rhs)
{
return static_cast<const ExtrusionFlow&>(lhs) == static_cast<const ExtrusionFlow&>(rhs) &&
lhs.role == rhs.role;
lhs.role == rhs.role && lhs.overhang_attributes == rhs.overhang_attributes;
}
class ExtrusionPath : public ExtrusionEntity

View File

@ -236,26 +236,14 @@ double VisibilityCalculator::get_angle_visibility_modifier(
return -angle_smooth_weight;
}
std::vector<Vec2d> extract_points(
const Perimeters::Perimeter &perimeter, const Perimeters::PointType point_type
) {
std::vector<Vec2d> result;
for (std::size_t i{0}; i < perimeter.positions.size(); ++i) {
if (perimeter.point_types[i] == point_type) {
result.push_back(perimeter.positions[i]);
}
}
return result;
}
std::vector<Vec2d> get_starting_positions(const Shells::Shell<> &shell) {
const Perimeters::Perimeter &perimeter{shell.front().boundary};
std::vector<Vec2d> enforcers{extract_points(perimeter, Perimeters::PointType::enforcer)};
std::vector<Vec2d> enforcers{Perimeters::extract_points(perimeter, Perimeters::PointType::enforcer)};
if (!enforcers.empty()) {
return enforcers;
}
std::vector<Vec2d> common{extract_points(perimeter, Perimeters::PointType::common)};
std::vector<Vec2d> common{Perimeters::extract_points(perimeter, Perimeters::PointType::common)};
if (!common.empty()) {
return common;
}

View File

@ -18,6 +18,9 @@ std::optional<SeamChoice> maybe_choose_seam_point(
return seam_choice;
}
}
if (!Perimeters::extract_points(perimeter, point_type).empty()) {
return std::nullopt;
}
}
return std::nullopt;

View File

@ -185,6 +185,19 @@ inline std::size_t get_layer_count(
}
return layer_count;
}
inline std::vector<Vec2d> extract_points(
const Perimeters::Perimeter &perimeter, const Perimeters::PointType point_type
) {
std::vector<Vec2d> result;
for (std::size_t i{0}; i < perimeter.positions.size(); ++i) {
if (perimeter.point_types[i] == point_type) {
result.push_back(perimeter.positions[i]);
}
}
return result;
}
} // namespace Slic3r::Seams::Perimeters
#endif // libslic3r_SeamPerimeters_hpp_

View File

@ -1173,7 +1173,7 @@ void Print::_make_skirt()
// Initial offset of the brim inner edge from the object (possible with a support & raft).
// The skirt will touch the brim if the brim is extruded.
auto distance = float(scale_(m_config.skirt_distance.value) - spacing/2.);
auto distance = float(scale_(m_config.skirt_distance.value - spacing/2.));
// Draw outlines from outside to inside.
// Loop while we have less skirts than required or any extruder hasn't reached the min length if any.
std::vector<coordf_t> extruded_length(extruders.size(), 0.);

View File

@ -13,6 +13,7 @@
#include <type_traits>
#include <vector>
#include "Point.hpp"
#include "libslic3r.h"
#include "Utils.hpp"

View File

@ -1560,7 +1560,7 @@ TriangleSelector::TriangleSplittingData TriangleSelector::serialize() const {
} else {
// In case this is leaf, we better save information about its state.
int n = int(tr.get_state());
if (n < static_cast<size_t>(TriangleStateType::Count))
if (n < static_cast<int>(TriangleStateType::Count))
data.used_states[n] = true;
if (n >= 3) {

View File

@ -203,6 +203,10 @@ void DSForLayers::draw_ticks(const ImRect& slideable_region)
if (ImGui::IsMouseHoveringRect(tick_hover_box.Min, tick_hover_box.Max)) {
ImGui::RenderFrame(tick_hover_box.Min, tick_hover_box.Max, tick_hovered_clr, false);
if (tick_it->type == ColorChange || tick_it->type == ToolChange) {
m_focus = fiTick;
ImGuiPureWrap::tooltip(get_tooltip(tick_it->tick), ImGui::GetFontSize() * 20.f);
}
break;
}
++tick_it;
@ -228,22 +232,22 @@ void DSForLayers::draw_ticks(const ImRect& slideable_region)
bool activate_this_tick = false;
if (tick_it == active_tick_it && m_allow_editing) {
// delete tick
if (render_button(ImGui::RemoveTick, ImGui::RemoveTickHovered, btn_label, icon_pos, m_ctrl.IsActiveHigherThumb() ? fiHigherThumb : fiLowerThumb, tick_it->tick)) {
if (render_button(ImGui::RemoveTick, ImGui::RemoveTickHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick)) {
m_ticks.ticks.erase(tick_it);
process_ticks_changed();
break;
}
}
else if (m_draw_mode != dmRegular)// if we have non-regular draw mode, all ticks should be marked with error icon
activate_this_tick = render_button(ImGui::ErrorTick, ImGui::ErrorTickHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick);
activate_this_tick = render_button(ImGui::ErrorTick, ImGui::ErrorTickHovered, btn_label, icon_pos, fiTick, tick_it->tick);
else if (tick_it->type == ColorChange || tick_it->type == ToolChange) {
if (m_ticks.is_conflict_tick(*tick_it, m_mode, m_values[tick_it->tick]))
activate_this_tick = render_button(ImGui::ErrorTick, ImGui::ErrorTickHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick);
activate_this_tick = render_button(ImGui::ErrorTick, ImGui::ErrorTickHovered, btn_label, icon_pos, fiTick, tick_it->tick);
}
else if (tick_it->type == CustomGCode::PausePrint)
activate_this_tick = render_button(ImGui::PausePrint, ImGui::PausePrintHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick);
activate_this_tick = render_button(ImGui::PausePrint, ImGui::PausePrintHovered, btn_label, icon_pos, fiTick, tick_it->tick);
else
activate_this_tick = render_button(ImGui::EditGCode, ImGui::EditGCodeHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick);
activate_this_tick = render_button(ImGui::EditGCode, ImGui::EditGCodeHovered, btn_label, icon_pos, fiTick, tick_it->tick);
if (activate_this_tick) {
m_ctrl.IsActiveHigherThumb() ? SetHigherPos(tick_it->tick) : SetLowerPos(tick_it->tick);
@ -297,10 +301,14 @@ void DSForLayers::draw_colored_band(const ImRect& groove, const ImRect& slideabl
ImRect main_band = ImRect(blank_rect);
main_band.Expand(blank_padding);
auto draw_band = [](const ImU32& clr, const ImRect& band_rc) {
auto draw_band = [this](const ImU32& clr, const ImRect& band_rc) {
ImGui::RenderFrame(band_rc.Min, band_rc.Max, clr, false, band_rc.GetWidth() * 0.5);
//cover round corner
ImGui::RenderFrame(ImVec2(band_rc.Min.x, band_rc.Max.y - band_rc.GetWidth() * 0.5), band_rc.Max, clr, false);
// add tooltip
if (ImGui::IsMouseHoveringRect(band_rc.Min, band_rc.Max))
m_focus = fiColorBand;
};
auto draw_main_band = [&main_band](const ImU32& clr) {
@ -315,6 +323,8 @@ void DSForLayers::draw_colored_band(const ImRect& groove, const ImRect& slideabl
static float tick_pos;
std::set<TickCode>::const_iterator tick_it = m_ticks.ticks.begin();
int rclicked_tick = -1;
while (tick_it != m_ticks.ticks.end())
{
//get position from tick
@ -337,13 +347,27 @@ void DSForLayers::draw_colored_band(const ImRect& groove, const ImRect& slideabl
ImU32 band_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f);
if (tick_it->tick == 0)
draw_main_band(band_clr);
else
else {
draw_band(band_clr, band_rect);
ImGuiContext& g = *GImGui;
if (ImGui::IsMouseHoveringRect(band_rect.Min, band_rect.Max) &&
g.IO.MouseClicked[1] && !m_ctrl.IsRClickOnThumb()) {
rclicked_tick = tick_it->tick;
}
}
}
}
}
tick_it++;
}
if (m_focus == fiColorBand) {
if (rclicked_tick > 0)
edit_tick(rclicked_tick);
else if (auto tip = get_tooltip(); !tip.empty())
ImGuiPureWrap::tooltip(tip, ImGui::GetFontSize() * 20.f);
}
}
void DSForLayers::render_menu()
@ -361,10 +385,13 @@ void DSForLayers::render_menu()
ImGui::OpenPopup("slider_add_tick_menu_popup");
else if (m_show_cog_menu)
ImGui::OpenPopup("cog_menu_popup");
else if (m_show_edit_menu)
ImGui::OpenPopup("edit_menu_popup");
if (can_edit())
render_add_tick_menu();
render_cog_menu();
render_edit_menu();
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(4);
@ -373,6 +400,7 @@ void DSForLayers::render_menu()
if (context.IO.MouseReleased[0]) {
m_show_just_color_change_menu = false;
m_show_cog_menu = false;
m_show_edit_menu = false;
}
}
@ -416,8 +444,10 @@ void DSForLayers::render_add_tick_menu()
}
}
void DSForLayers::render_multi_extruders_menu()
bool DSForLayers::render_multi_extruders_menu(bool switch_current_code/* = false*/)
{
bool ret = false;
std::vector<std::string> colors;
if (m_cb_get_extruder_colors)
colors = m_cb_get_extruder_colors();
@ -428,7 +458,7 @@ void DSForLayers::render_multi_extruders_menu()
const int tick = m_ctrl.GetActivePos();
if (m_mode == MultiAsSingle) {
const std::string menu_name = _u8L("Change extruder");
const std::string menu_name = switch_current_code ? _u8L("Switch code to Change extruder") : _u8L("Change extruder");
if (ImGuiPureWrap::begin_menu(menu_name.c_str())) {
std::array<int, 2> active_extruders = m_ticks.get_active_extruders_for_tick(tick, m_mode);
for (int i = 1; i <= extruders_cnt; i++) {
@ -439,14 +469,18 @@ void DSForLayers::render_multi_extruders_menu()
std::array<float, 4> rgba = decode_color_to_float_array(colors[i - 1]);
ImU32 icon_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f);
if (ImGuiPureWrap::menu_item_with_icon(item_name.c_str(), "", ImVec2(14, 14) * m_scale, icon_clr, false, !is_active_extruder))
if (ImGuiPureWrap::menu_item_with_icon(item_name.c_str(), "", ImVec2(14, 14) * m_scale, icon_clr, false, !is_active_extruder)) {
add_code_as_tick(ToolChange, i);
ret = true;
}
}
ImGuiPureWrap::end_menu();
}
}
const std::string menu_name = format(_u8L("Add color change (%1%) for:"), gcode(ColorChange));
const std::string menu_name = switch_current_code ?
format(_u8L("Switch code to Color change (%1%) for:"), gcode(ColorChange)) :
format(_u8L("Add color change (%1%) for:"), gcode(ColorChange));
if (ImGuiPureWrap::begin_menu(menu_name.c_str())) {
std::set<int> used_extruders_for_tick = m_ticks.get_used_extruders_for_tick(tick, m_values[tick]);
@ -457,12 +491,15 @@ void DSForLayers::render_multi_extruders_menu()
if (is_used_extruder)
item_name += " (" + _u8L("used") + ")";
if (ImGuiPureWrap::menu_item_with_icon(item_name.c_str(), ""))
if (ImGuiPureWrap::menu_item_with_icon(item_name.c_str(), "")) {
add_code_as_tick(ColorChange, i);
ret = true;
}
}
ImGuiPureWrap::end_menu();
}
}
return ret;
}
void DSForLayers::render_color_picker()
@ -519,6 +556,50 @@ void DSForLayers::render_cog_menu()
}
}
void DSForLayers::render_edit_menu()
{
if (!m_show_edit_menu)
return;
const ImVec2 icon_sz = ImVec2(14, 14);
if (m_ticks.has_tick(m_ctrl.GetActivePos()) && ImGui::BeginPopup("edit_menu_popup")) {
std::set<TickCode>::iterator it = m_ticks.ticks.find(TickCode{ m_ctrl.GetActivePos()});
if (it->type == ToolChange) {
if (render_multi_extruders_menu(true)) {
ImGui::EndPopup();
return;
}
}
else {
std::string edit_item_name = it->type == CustomGCode::ColorChange ? _u8L("Edit color") :
it->type == CustomGCode::PausePrint ? _u8L("Edit pause print message") :
_u8L("Edit custom G-code");
if (ImGuiPureWrap::menu_item_with_icon(edit_item_name.c_str(), "")) {
edit_tick();
ImGui::EndPopup();
return;
}
}
if (it->type == ColorChange && m_mode == MultiAsSingle) {
if (render_multi_extruders_menu(true)) {
ImGui::EndPopup();
return;
}
}
std::string delete_item_name = it->type == CustomGCode::ColorChange ? _u8L("Delete color change") :
it->type == CustomGCode::ToolChange ? _u8L("Delete tool change") :
it->type == CustomGCode::PausePrint ? _u8L("Delete pause print") :
_u8L("Delete custom G-code");
if (ImGuiPureWrap::menu_item_with_icon(delete_item_name.c_str(), ""))
delete_current_tick();
ImGui::EndPopup();
}
}
bool DSForLayers::render_button(const wchar_t btn_icon, const wchar_t btn_icon_hovered, const std::string& label_id, const ImVec2& pos, FocusedItem focus, int tick /*= -1*/)
{
ImGui::PushStyleVar(ImGuiStyleVar_::ImGuiStyleVar_WindowBorderSize, 0);
@ -547,6 +628,9 @@ bool DSForLayers::render_button(const wchar_t btn_icon, const wchar_t btn_icon_h
ImGui::SetCursorPos(ImVec2(0, 0));
const bool ret = m_imgui->image_button(g.HoveredWindow == g.CurrentWindow ? btn_icon_hovered : btn_icon, tooltip, false);
if (tick > 0 && tick == m_ctrl.GetActivePos() && g.HoveredWindow == g.CurrentWindow && g.IO.MouseClicked[1])
m_show_edit_menu = true;
ImGuiPureWrap::end();
ImGui::PopStyleColor(2);
@ -814,7 +898,7 @@ std::string DSForLayers::get_tooltip(int tick/*=-1*/)
"or Set ruler mode")) % "(Shift + G)").str();
}
if (m_focus == fiColorBand)
return m_mode != SingleExtruder ? "" :
return m_mode != SingleExtruder || !can_edit() ? "" :
_u8L("Edit current color - Right click the colored slider segment");
if (m_focus == fiSmartWipeTower)
return _u8L("This is wipe tower layer");
@ -884,7 +968,7 @@ std::string DSForLayers::get_tooltip(int tick/*=-1*/)
};
tooltip +=
tick_code_it->type == ColorChange ?
(m_mode == SingleExtruder ?
(m_mode == SingleExtruder && tick_code_it->extruder==1 ?
format(_u8L("Color change (\"%1%\")"), gcode(ColorChange)) :
format(_u8L("Color change (\"%1%\") for Extruder %2%"), gcode(ColorChange), tick_code_it->extruder)) :
tick_code_it->type == CustomGCode::PausePrint ?

View File

@ -31,8 +31,6 @@ enum FocusedItem {
fiCogIcon,
fiColorBand,
fiActionIcon,
fiLowerThumb,
fiHigherThumb,
fiSmartWipeTower,
fiTick
};
@ -138,6 +136,7 @@ private:
bool m_allow_editing { true };
bool m_show_estimated_times { false };
bool m_show_cog_menu { false };
bool m_show_edit_menu { false };
DrawMode m_draw_mode { dmRegular };
Mode m_mode { SingleExtruder };
@ -163,6 +162,7 @@ private:
void draw_ticks(const ImRect& slideable_region);
void render_menu();
void render_cog_menu();
void render_edit_menu();
bool render_button(const wchar_t btn_icon, const wchar_t btn_icon_hovered, const std::string& label_id, const ImVec2& pos, FocusedItem focus, int tick = -1);
void add_code_as_tick(Type type, int selected_extruder = -1);
@ -188,7 +188,7 @@ private:
std::string m_selectable_color;
void render_add_tick_menu();
void render_multi_extruders_menu();
bool render_multi_extruders_menu(bool switch_current_code = false);
bool render_jump_to_window(const ImVec2& pos, double* active_value, double min_z, double max_z);
void render_color_picker();

View File

@ -1048,7 +1048,7 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect)
this->SetFont(this->normal_font());
#ifdef _WIN32
if (m_tmp_top_bar->IsShown())
if (m_tmp_top_bar && m_tmp_top_bar->IsShown())
m_tmp_top_bar->Rescale();
m_tabpanel->Rescale();
#endif

View File

@ -35,7 +35,6 @@
#include <pwd.h>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/process.hpp>
#endif

View File

@ -832,8 +832,14 @@ std::pair<BoundingBoxf3, Transform3d> Selection::get_bounding_box_in_reference_s
const GLVolume& vol = *get_volume(id);
const Transform3d vol_world_rafo = vol.world_matrix();
const TriangleMesh* mesh = vol.convex_hull();
if (mesh == nullptr)
if (mesh == nullptr) {
// workaround to avoid a crash, see spe-2295 -> Crash when re-cutting with dowel connectors
const int obj_id = vol.object_idx();
const int vol_id = vol.volume_idx();
if (m_model->objects[obj_id]->volumes.size() <= vol_id)
continue;
mesh = &m_model->objects[vol.object_idx()]->volumes[vol.volume_idx()]->mesh();
}
assert(mesh != nullptr);
for (const stl_vertex& v : mesh->its.vertices) {
const Vec3d world_v = vol_world_rafo * v.cast<double>();