Fixed conflicts after merge with master

This commit is contained in:
enricoturri1966 2021-05-13 14:10:42 +02:00
commit 6bddacee44
90 changed files with 4276 additions and 4185 deletions

View file

@ -134,27 +134,9 @@ void Size::set_scale_factor(int scale_factor)
m_scale_factor = scale_factor;
}
GLCanvas3D::LayersEditing::LayersEditing()
: m_enabled(false)
, m_z_texture_id(0)
, m_model_object(nullptr)
, m_object_max_z(0.f)
, m_slicing_parameters(nullptr)
, m_layer_height_profile_modified(false)
, m_adaptive_quality(0.5f)
, state(Unknown)
, band_width(2.0f)
, strength(0.005f)
, last_object_id(-1)
, last_z(0.0f)
, last_action(LAYER_HEIGHT_EDIT_ACTION_INCREASE)
{
}
GLCanvas3D::LayersEditing::~LayersEditing()
{
if (m_z_texture_id != 0)
{
if (m_z_texture_id != 0) {
glsafe(::glDeleteTextures(1, &m_z_texture_id));
m_z_texture_id = 0;
}
@ -186,11 +168,18 @@ void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config)
void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
{
const ModelObject *model_object_new = (object_id >= 0) ? model.objects[object_id] : nullptr;
#if ENABLE_ALLOW_NEGATIVE_Z
// Maximum height of an object changes when the object gets rotated or scaled.
// Changing maximum height of an object will invalidate the layer heigth editing profile.
// m_model_object->bounding_box() is cached, therefore it is cheap even if this method is called frequently.
const float new_max_z = (model_object_new == nullptr) ? 0.0f : static_cast<float>(model_object_new->bounding_box().max.z());
#else
// Maximum height of an object changes when the object gets rotated or scaled.
// Changing maximum height of an object will invalidate the layer heigth editing profile.
// m_model_object->raw_bounding_box() is cached, therefore it is cheap even if this method is called frequently.
float new_max_z = (model_object_new == nullptr) ? 0.f : model_object_new->raw_bounding_box().size().z();
if (m_model_object != model_object_new || this->last_object_id != object_id || m_object_max_z != new_max_z ||
#endif // ENABLE_ALLOW_NEGATIVE_Z
if (m_model_object != model_object_new || this->last_object_id != object_id || m_object_max_z != new_max_z ||
(model_object_new != nullptr && m_model_object->id() != model_object_new->id())) {
m_layer_height_profile.clear();
m_layer_height_profile_modified = false;
@ -218,7 +207,7 @@ void GLCanvas3D::LayersEditing::set_enabled(bool enabled)
m_enabled = is_allowed() && enabled;
}
float GLCanvas3D::LayersEditing::s_overelay_window_width;
float GLCanvas3D::LayersEditing::s_overlay_window_width;
void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
{
@ -302,7 +291,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
if (imgui.button(_L("Reset")))
wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE));
GLCanvas3D::LayersEditing::s_overelay_window_width = ImGui::GetWindowSize().x /*+ (float)m_layers_texture.width/4*/;
GLCanvas3D::LayersEditing::s_overlay_window_width = ImGui::GetWindowSize().x /*+ (float)m_layers_texture.width/4*/;
imgui.end();
const Rect& bar_rect = get_bar_rect_viewport(canvas);
@ -319,7 +308,7 @@ float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
float t = rect.get_top();
float b = rect.get_bottom();
return ((rect.get_left() <= x) && (x <= rect.get_right()) && (t <= y) && (y <= b)) ?
return (rect.get_left() <= x && x <= rect.get_right() && t <= y && y <= b) ?
// Inside the bar.
(b - y - 1.0f) / (b - t - 1.0f) :
// Outside the bar.
@ -329,7 +318,7 @@ float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
bool GLCanvas3D::LayersEditing::bar_rect_contains(const GLCanvas3D& canvas, float x, float y)
{
const Rect& rect = get_bar_rect_screen(canvas);
return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom());
return rect.get_left() <= x && x <= rect.get_right() && rect.get_top() <= y && y <= rect.get_bottom();
}
Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas)
@ -338,7 +327,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas)
float w = (float)cnv_size.get_width();
float h = (float)cnv_size.get_height();
return Rect(w - thickness_bar_width(canvas), 0.0f, w, h);
return { w - thickness_bar_width(canvas), 0.0f, w, h };
}
Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
@ -347,7 +336,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
float half_w = 0.5f * (float)cnv_size.get_width();
float half_h = 0.5f * (float)cnv_size.get_height();
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
return { (half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom };
}
bool GLCanvas3D::LayersEditing::is_initialized() const
@ -365,11 +354,12 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con
float h = 0.0f;
for (size_t i = m_layer_height_profile.size() - 2; i >= 2; i -= 2) {
float zi = m_layer_height_profile[i];
float zi_1 = m_layer_height_profile[i - 2];
const float zi = static_cast<float>(m_layer_height_profile[i]);
const float zi_1 = static_cast<float>(m_layer_height_profile[i - 2]);
if (zi_1 <= z && z <= zi) {
float dz = zi - zi_1;
h = (dz != 0.0f) ? lerp(m_layer_height_profile[i - 1], m_layer_height_profile[i + 1], (z - zi_1) / dz) : m_layer_height_profile[i + 1];
h = (dz != 0.0f) ? static_cast<float>(lerp(m_layer_height_profile[i - 1], m_layer_height_profile[i + 1], (z - zi_1) / dz)) :
static_cast<float>(m_layer_height_profile[i + 1]);
break;
}
}
@ -398,10 +388,10 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3
glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
// Render the color bar
float l = bar_rect.get_left();
float r = bar_rect.get_right();
float t = bar_rect.get_top();
float b = bar_rect.get_bottom();
const float l = bar_rect.get_left();
const float r = bar_rect.get_right();
const float t = bar_rect.get_top();
const float b = bar_rect.get_bottom();
::glBegin(GL_QUADS);
::glNormal3f(0.0f, 0.0f, 1.0f);
@ -564,7 +554,7 @@ void GLCanvas3D::LayersEditing::accept_changes(GLCanvas3D& canvas)
{
if (last_object_id >= 0) {
if (m_layer_height_profile_modified) {
wxGetApp().plater()->take_snapshot(_(L("Variable layer height - Manual edit")));
wxGetApp().plater()->take_snapshot(_L("Variable layer height - Manual edit"));
const_cast<ModelObject*>(m_model_object)->layer_height_profile.set(m_layer_height_profile);
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
wxGetApp().obj_list()->update_info_items(last_object_id);
@ -577,7 +567,7 @@ void GLCanvas3D::LayersEditing::update_slicing_parameters()
{
if (m_slicing_parameters == nullptr) {
m_slicing_parameters = new SlicingParameters();
*m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z);
*m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z);
}
}
@ -614,278 +604,6 @@ GLCanvas3D::Mouse::Mouse()
{
}
#if !ENABLE_WARNING_TEXTURE_REMOVAL
const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 120, 120, 120 };//{ 9, 91, 134 };
const unsigned char GLCanvas3D::WarningTexture::Opacity = 255;
GLCanvas3D::WarningTexture::WarningTexture()
: GUI::GLTexture()
, m_original_width(0)
, m_original_height(0)
{
}
void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas)
{
// Since we have NotificationsManager.hpp the warning textures are no loger needed.
// However i have left the infrastructure here and only commented the rendering.
// The plater warning / error notifications are added and closed from here.
std::string text;
bool error = false;
switch (warning) {
case ObjectOutside: text = _u8L("An object outside the print area was detected."); break;
case ToolpathOutside: text = _u8L("A toolpath outside the print area was detected."); error = true; break;
case SlaSupportsOutside: text = _u8L("SLA supports outside the print area were detected."); error = true; break;
case SomethingNotShown: text = _u8L("Some objects are not visible."); break;
case ObjectClashed:
text = _u8L( "An object outside the print area was detected.\n"
"Resolve the current problem to continue slicing.");
error = true;
break;
}
BOOST_LOG_TRIVIAL(error) << state << " : " << text ;
auto &notification_manager = *wxGetApp().plater()->get_notification_manager();
if (state) {
if(error)
notification_manager.push_plater_error_notification(text);
else
notification_manager.push_plater_warning_notification(text);
} else {
if (error)
notification_manager.close_plater_error_notification(text);
else
notification_manager.close_plater_warning_notification(text);
}
/*
auto it = std::find(m_warnings.begin(), m_warnings.end(), warning);
if (state) {
if (it != m_warnings.end()) // this warning is already set to be shown
return;
m_warnings.push_back(warning);
std::sort(m_warnings.begin(), m_warnings.end());
}
else {
if (it == m_warnings.end()) // deactivating something that is not active is an easy task
return;
m_warnings.erase(it);
if (m_warnings.empty()) { // nothing remains to be shown
reset();
m_msg_text = "";// save information for rescaling
return;
}
}
// Look at the end of our vector and generate proper texture.
std::string text;
bool red_colored = false;
switch (m_warnings.back()) {
case ObjectOutside : text = L("An object outside the print area was detected"); break;
case ToolpathOutside : text = L("A toolpath outside the print area was detected"); break;
case SlaSupportsOutside : text = L("SLA supports outside the print area were detected"); break;
case SomethingNotShown : text = L("Some objects are not visible when editing supports"); break;
case ObjectClashed: {
text = L("An object outside the print area was detected\n"
"Resolve the current problem to continue slicing");
red_colored = true;
break;
}
}
generate(text, canvas, true, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...)
// save information for rescaling
m_msg_text = text;
m_is_colored_red = red_colored;
*/
}
#ifdef __WXMSW__
static bool is_font_cleartype(const wxFont &font)
{
// Native font description: on MSW, it is a version number plus the content of LOGFONT, separated by semicolon.
wxString font_desc = font.GetNativeFontInfoDesc();
// Find the quality field.
wxString sep(";");
size_t startpos = 0;
for (size_t i = 0; i < 12; ++ i)
startpos = font_desc.find(sep, startpos + 1);
++ startpos;
size_t endpos = font_desc.find(sep, startpos);
int quality = wxAtoi(font_desc(startpos, endpos - startpos));
return quality == CLEARTYPE_QUALITY;
}
// ClearType produces renders, which are difficult to convert into an alpha blended OpenGL texture.
// Therefore it is better to disable it, though Vojtech found out, that the font returned with ClearType
// disabled is signifcantly thicker than the default ClearType font.
// This function modifies the font provided.
static void msw_disable_cleartype(wxFont &font)
{
// Native font description: on MSW, it is a version number plus the content of LOGFONT, separated by semicolon.
wxString font_desc = font.GetNativeFontInfoDesc();
// Find the quality field.
wxString sep(";");
size_t startpos_weight = 0;
for (size_t i = 0; i < 5; ++ i)
startpos_weight = font_desc.find(sep, startpos_weight + 1);
++ startpos_weight;
size_t endpos_weight = font_desc.find(sep, startpos_weight);
// Parse the weight field.
unsigned int weight = wxAtoi(font_desc(startpos_weight, endpos_weight - startpos_weight));
size_t startpos = endpos_weight;
for (size_t i = 0; i < 6; ++ i)
startpos = font_desc.find(sep, startpos + 1);
++ startpos;
size_t endpos = font_desc.find(sep, startpos);
int quality = wxAtoi(font_desc(startpos, endpos - startpos));
if (quality == CLEARTYPE_QUALITY) {
// Replace the weight with a smaller value to compensate the weight of non ClearType font.
wxString sweight = std::to_string(weight * 2 / 4);
size_t len_weight = endpos_weight - startpos_weight;
wxString squality = std::to_string(ANTIALIASED_QUALITY);
font_desc.replace(startpos_weight, len_weight, sweight);
font_desc.replace(startpos + sweight.size() - len_weight, endpos - startpos, squality);
font.SetNativeFontInfo(font_desc);
wxString font_desc2 = font.GetNativeFontInfoDesc();
}
wxString font_desc2 = font.GetNativeFontInfoDesc();
}
#endif /* __WXMSW__ */
bool GLCanvas3D::WarningTexture::generate(const std::string& msg_utf8, const GLCanvas3D& canvas, bool compress, bool red_colored/* = false*/)
{
reset();
if (msg_utf8.empty())
return false;
wxString msg = _(msg_utf8);
wxMemoryDC memDC;
#ifdef __WXMSW__
// set scaled application normal font as default font
wxFont font = wxGetApp().normal_font();
#else
// select default font
const float scale = canvas.get_canvas_size().get_scale_factor();
#if ENABLE_RETINA_GL
// For non-visible or non-created window getBackingScaleFactor function return 0.0 value.
// And using of the zero scale causes a crash, when we trying to draw text to the (0,0) rectangle
// https://github.com/prusa3d/PrusaSlicer/issues/3916
if (scale <= 0.0f)
return false;
#endif
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale);
#endif
font.MakeLarger();
font.MakeBold();
memDC.SetFont(font);
// calculates texture size
wxCoord w, h;
memDC.GetMultiLineTextExtent(msg, &w, &h);
m_original_width = (int)w;
m_original_height = (int)h;
m_width = (int)next_highest_power_of_2((uint32_t)w);
m_height = (int)next_highest_power_of_2((uint32_t)h);
// generates bitmap
wxBitmap bitmap(m_width, m_height);
memDC.SelectObject(bitmap);
memDC.SetBackground(wxBrush(*wxBLACK));
memDC.Clear();
// draw message
memDC.SetTextForeground(*wxRED);
memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER);
memDC.SelectObject(wxNullBitmap);
// Convert the bitmap into a linear data ready to be loaded into the GPU.
wxImage image = bitmap.ConvertToImage();
// prepare buffer
std::vector<unsigned char> data(4 * m_width * m_height, 0);
const unsigned char *src = image.GetData();
for (int h = 0; h < m_height; ++h) {
unsigned char* dst = data.data() + 4 * h * m_width;
for (int w = 0; w < m_width; ++w) {
*dst++ = 255;
if (red_colored) {
*dst++ = 72; // 204
*dst++ = 65; // 204
} else {
*dst++ = 255;
*dst++ = 255;
}
*dst++ = (unsigned char)std::min<int>(255, *src);
src += 3;
}
}
// sends buffer to gpu
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(::glGenTextures(1, &m_id));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
if (compress && GLEW_EXT_texture_compression_s3tc)
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
else
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
return true;
}
void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
{
if (m_warnings.empty())
return;
if (m_id > 0 && m_original_width > 0 && m_original_height > 0 && m_width > 0 && m_height > 0) {
const Size& cnv_size = canvas.get_canvas_size();
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
float left = (-0.5f * (float)m_original_width) * inv_zoom;
float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom;
float right = left + (float)m_original_width * inv_zoom;
float bottom = top - (float)m_original_height * inv_zoom;
float uv_left = 0.0f;
float uv_top = 0.0f;
float uv_right = (float)m_original_width / (float)m_width;
float uv_bottom = (float)m_original_height / (float)m_height;
GLTexture::Quad_UVs uvs;
uvs.left_top = { uv_left, uv_top };
uvs.left_bottom = { uv_left, uv_bottom };
uvs.right_bottom = { uv_right, uv_bottom };
uvs.right_top = { uv_right, uv_top };
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
}
}
void GLCanvas3D::WarningTexture::msw_rescale(const GLCanvas3D& canvas)
{
if (m_msg_text.empty())
return;
generate(m_msg_text, canvas, true, m_is_colored_red);
}
#endif // !ENABLE_WARNING_TEXTURE_REMOVAL
void GLCanvas3D::Labels::render(const std::vector<const ModelInstance*>& sorted_instances) const
{
if (!m_enabled || !is_shown())
@ -1153,8 +871,6 @@ void GLCanvas3D::SequentialPrintClearance::render() const
}
#endif // ENABLE_SEQUENTIAL_LIMITS
float GLCanvas3D::Slope::s_window_width;
wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent);
@ -1388,11 +1104,7 @@ void GLCanvas3D::reset_volumes()
m_volumes.clear();
m_dirty = true;
#if ENABLE_WARNING_TEXTURE_REMOVAL
_set_warning_notification(EWarning::ObjectOutside, false);
#else
_set_warning_texture(WarningTexture::ObjectOutside, false);
#endif // ENABLE_WARNING_TEXTURE_REMOVAL
}
int GLCanvas3D::check_volumes_outside_state() const
@ -1446,19 +1158,11 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject
if (visible && !mo)
toggle_sla_auxiliaries_visibility(true, mo, instance_idx);
#if ENABLE_WARNING_TEXTURE_REMOVAL
if (!mo && !visible && !m_model->objects.empty() && (m_model->objects.size() > 1 || m_model->objects.front()->instances.size() > 1))
_set_warning_notification(EWarning::SomethingNotShown, true);
if (!mo && visible)
_set_warning_notification(EWarning::SomethingNotShown, false);
#else
if (!mo && !visible && !m_model->objects.empty() && (m_model->objects.size() > 1 || m_model->objects.front()->instances.size() > 1))
_set_warning_texture(WarningTexture::SomethingNotShown, true);
if (!mo && visible)
_set_warning_texture(WarningTexture::SomethingNotShown, false);
#endif // ENABLE_WARNING_TEXTURE_REMOVAL
}
void GLCanvas3D::update_instance_printable_state_for_object(const size_t obj_idx)
@ -1812,6 +1516,11 @@ void GLCanvas3D::render()
}
#endif // ENABLE_RENDER_STATISTICS
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
if (wxGetApp().is_editor() && wxGetApp().plater()->is_view3D_shown())
wxGetApp().plater()->render_project_state_debug_window();
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
#if ENABLE_CAMERA_STATISTICS
camera.debug_render();
#endif // ENABLE_CAMERA_STATISTICS
@ -2045,7 +1754,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
m_reload_delayed = !m_canvas->IsShown() && !refresh_immediately && !force_full_scene_refresh;
PrinterTechnology printer_technology = m_process->current_printer_technology();
PrinterTechnology printer_technology = current_printer_technology();
int volume_idx_wipe_tower_old = -1;
// Release invalidated volumes to conserve GPU memory in case of delayed refresh (see m_reload_delayed).
@ -2335,31 +2044,18 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
bool fullyOut = false;
const bool contained_min_one = m_volumes.check_outside_state(m_config, partlyOut, fullyOut);
#if ENABLE_WARNING_TEXTURE_REMOVAL
_set_warning_notification(EWarning::ObjectClashed, partlyOut);
_set_warning_notification(EWarning::ObjectOutside, fullyOut);
if (printer_technology != ptSLA || !contained_min_one)
_set_warning_notification(EWarning::SlaSupportsOutside, false);
#else
_set_warning_texture(WarningTexture::ObjectClashed, partlyOut);
_set_warning_texture(WarningTexture::ObjectOutside, fullyOut);
if(printer_technology != ptSLA || !contained_min_one)
_set_warning_texture(WarningTexture::SlaSupportsOutside, false);
#endif // ENABLE_WARNING_TEXTURE_REMOVAL
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS,
contained_min_one && !m_model->objects.empty() && !partlyOut));
}
else {
#if ENABLE_WARNING_TEXTURE_REMOVAL
_set_warning_notification(EWarning::ObjectOutside, false);
_set_warning_notification(EWarning::ObjectClashed, false);
_set_warning_notification(EWarning::SlaSupportsOutside, false);
#else
_set_warning_texture(WarningTexture::ObjectOutside, false);
_set_warning_texture(WarningTexture::ObjectClashed, false);
_set_warning_texture(WarningTexture::SlaSupportsOutside, false);
#endif // ENABLE_WARNING_TEXTURE_REMOVAL
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false));
}
@ -2402,11 +2098,7 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result)
if (wxGetApp().is_editor()) {
m_gcode_viewer.update_shells_color_by_extruder(m_config);
#if ENABLE_WARNING_TEXTURE_REMOVAL
_set_warning_notification_if_needed(EWarning::ToolpathOutside);
#else
_show_warning_texture_if_needed(WarningTexture::ToolpathOutside);
#endif // ENABLE_WARNING_TEXTURE_REMOVAL
}
}
@ -2433,11 +2125,7 @@ void GLCanvas3D::load_sla_preview()
this->reset_volumes();
_load_sla_shells();
_update_sla_shells_outside_state();
#if ENABLE_WARNING_TEXTURE_REMOVAL
_set_warning_notification_if_needed(EWarning::SlaSupportsOutside);
#else
_show_warning_texture_if_needed(WarningTexture::SlaSupportsOutside);
#endif // ENABLE_WARNING_TEXTURE_REMOVAL
}
}
@ -2458,11 +2146,7 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, c
_load_print_object_toolpaths(*object, str_tool_colors, color_print_values);
_update_toolpath_volumes_outside_state();
#if ENABLE_WARNING_TEXTURE_REMOVAL
_set_warning_notification_if_needed(EWarning::ToolpathOutside);
#else
_show_warning_texture_if_needed(WarningTexture::ToolpathOutside);
#endif // ENABLE_WARNING_TEXTURE_REMOVAL
}
void GLCanvas3D::bind_event_handlers()
@ -2608,9 +2292,19 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
#ifdef _WIN32
if (wxGetApp().app_config->get("use_legacy_3DConnexion") == "1") {
#endif //_WIN32
#ifdef __APPLE__
// On OSX use Cmd+Shift+M to "Show/Hide 3Dconnexion devices settings dialog"
if ((evt.GetModifiers() & shiftMask) != 0) {
#endif // __APPLE__
Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller();
controller.show_settings_dialog(!controller.is_settings_dialog_shown());
m_dirty = true;
#ifdef __APPLE__
}
else
// and Cmd+M to minimize application
wxGetApp().mainframe->Iconize();
#endif // __APPLE__
#ifdef _WIN32
}
#endif //_WIN32
@ -3246,7 +2940,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
if (m_gizmos.on_mouse(evt)) {
if (wxWindow::FindFocus() != this->m_canvas)
if (wxWindow::FindFocus() != m_canvas)
// Grab keyboard focus for input in gizmo dialogs.
m_canvas->SetFocus();
@ -3269,7 +2963,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.set_move_start_threshold_position_2D_as_invalid();
}
if (evt.ButtonDown() && wxWindow::FindFocus() != this->m_canvas)
if (evt.ButtonDown() && wxWindow::FindFocus() != m_canvas)
// Grab keyboard focus on any mouse click event.
m_canvas->SetFocus();
@ -3662,14 +3356,38 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
wipe_tower_origin = v->get_volume_offset();
}
#if ENABLE_ALLOW_NEGATIVE_Z
// Fixes flying instances
#else
// Fixes sinking/flying instances
#endif // ENABLE_ALLOW_NEGATIVE_Z
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
#if ENABLE_ALLOW_NEGATIVE_Z
double shift_z = m->get_instance_min_z(i.second);
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
if (current_printer_technology() == ptSLA || shift_z > 0.0) {
#else
if (shift_z > 0.0) {
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
Vec3d shift(0.0, 0.0, -shift_z);
#else
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
#endif // ENABLE_ALLOW_NEGATIVE_Z
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
#if ENABLE_ALLOW_NEGATIVE_Z
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
}
#if ENABLE_ALLOW_NEGATIVE_Z
// if the selection is not valid to allow for layer editing after the move, we need to turn off the tool if it is running
// similar to void Plater::priv::selection_changed()
if (!wxGetApp().plater()->can_layers_editing() && is_layers_editing_enabled())
post_event(SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING));
#endif // ENABLE_ALLOW_NEGATIVE_Z
if (object_moved)
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED));
@ -3687,18 +3405,30 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
if (!snapshot_type.empty())
wxGetApp().plater()->take_snapshot(_(snapshot_type));
#if ENABLE_ALLOW_NEGATIVE_Z
// stores current min_z of instances
std::map<std::pair<int, int>, double> min_zs;
if (!snapshot_type.empty()) {
for (int i = 0; i < static_cast<int>(m_model->objects.size()); ++i) {
const ModelObject* obj = m_model->objects[i];
for (int j = 0; j < static_cast<int>(obj->instances.size()); ++j) {
min_zs[{ i, j }] = obj->instance_bounding_box(j).min(2);
}
}
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
std::set<std::pair<int, int>> done; // keeps track of modified instances
Selection::EMode selection_mode = m_selection.get_mode();
for (const GLVolume* v : m_volumes.volumes)
{
for (const GLVolume* v : m_volumes.volumes) {
int object_idx = v->object_idx();
if (object_idx == 1000) { // the wipe tower
Vec3d offset = v->get_volume_offset();
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset(0), offset(1), v->get_volume_rotation()(2))));
}
if ((object_idx < 0) || ((int)m_model->objects.size() <= object_idx))
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
continue;
int instance_idx = v->instance_idx();
@ -3708,15 +3438,12 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
// Rotate instances/volumes.
ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr)
{
if (selection_mode == Selection::Instance)
{
if (model_object != nullptr) {
if (selection_mode == Selection::Instance) {
model_object->instances[instance_idx]->set_rotation(v->get_instance_rotation());
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
}
else if (selection_mode == Selection::Volume)
{
else if (selection_mode == Selection::Volume) {
model_object->volumes[volume_idx]->set_rotation(v->get_volume_rotation());
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
}
@ -3725,12 +3452,21 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
}
// Fixes sinking/flying instances
for (const std::pair<int, int>& i : done)
{
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
#if ENABLE_ALLOW_NEGATIVE_Z
double shift_z = m->get_instance_min_z(i.second);
// leave sinking instances as sinking
if (min_zs.empty() || min_zs.find({ i.first, i.second })->second >= 0.0 || shift_z > 0.0) {
Vec3d shift(0.0, 0.0, -shift_z);
#else
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
#endif // ENABLE_ALLOW_NEGATIVE_Z
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
#if ENABLE_ALLOW_NEGATIVE_Z
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
}
if (!done.empty())
@ -3747,14 +3483,26 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
if (!snapshot_type.empty())
wxGetApp().plater()->take_snapshot(_(snapshot_type));
#if ENABLE_ALLOW_NEGATIVE_Z
// stores current min_z of instances
std::map<std::pair<int, int>, double> min_zs;
if (!snapshot_type.empty()) {
for (int i = 0; i < static_cast<int>(m_model->objects.size()); ++i) {
const ModelObject* obj = m_model->objects[i];
for (int j = 0; j < static_cast<int>(obj->instances.size()); ++j) {
min_zs[{ i, j }] = obj->instance_bounding_box(j).min(2);
}
}
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
std::set<std::pair<int, int>> done; // keeps track of modified instances
Selection::EMode selection_mode = m_selection.get_mode();
for (const GLVolume* v : m_volumes.volumes)
{
for (const GLVolume* v : m_volumes.volumes) {
int object_idx = v->object_idx();
if ((object_idx < 0) || ((int)m_model->objects.size() <= object_idx))
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
continue;
int instance_idx = v->instance_idx();
@ -3764,15 +3512,12 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
// Rotate instances/volumes
ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr)
{
if (selection_mode == Selection::Instance)
{
if (model_object != nullptr) {
if (selection_mode == Selection::Instance) {
model_object->instances[instance_idx]->set_scaling_factor(v->get_instance_scaling_factor());
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
}
else if (selection_mode == Selection::Volume)
{
else if (selection_mode == Selection::Volume) {
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
model_object->volumes[volume_idx]->set_scaling_factor(v->get_volume_scaling_factor());
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
@ -3782,16 +3527,25 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
}
// Fixes sinking/flying instances
for (const std::pair<int, int>& i : done)
{
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
#if ENABLE_ALLOW_NEGATIVE_Z
double shift_z = m->get_instance_min_z(i.second);
// leave sinking instances as sinking
if (min_zs.empty() || min_zs.find({ i.first, i.second })->second >= 0.0 || shift_z > 0.0) {
Vec3d shift(0.0, 0.0, -shift_z);
#else
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
#endif // ENABLE_ALLOW_NEGATIVE_Z
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
#if ENABLE_ALLOW_NEGATIVE_Z
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
}
if (!done.empty())
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_ROTATED));
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_SCALED));
m_dirty = true;
}
@ -3950,16 +3704,13 @@ void GLCanvas3D::set_cursor(ECursorType type)
void GLCanvas3D::msw_rescale()
{
#if !ENABLE_WARNING_TEXTURE_REMOVAL
m_warning_texture.msw_rescale(*this);
#endif // !ENABLE_WARNING_TEXTURE_REMOVAL
}
void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar()
{
std::string new_tooltip = _u8L("Switch to Settings") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ;
m_main_toolbar.set_tooltip(get_main_toolbar_item_id("settings"), new_tooltip);
@ -3967,11 +3718,7 @@ void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar()
bool GLCanvas3D::has_toolpaths_to_export() const
{
#if ENABLE_SPLITTED_VERTEX_BUFFER
return m_gcode_viewer.can_export_toolpaths();
#else
return m_gcode_viewer.has_data();
#endif // ENABLE_SPLITTED_VERTEX_BUFFER
}
void GLCanvas3D::export_toolpaths_to_obj(const char* filename) const
@ -4113,7 +3860,7 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x)
ArrangeSettings &settings_out = get_arrange_settings();
auto &appcfg = wxGetApp().app_config;
PrinterTechnology ptech = m_process->current_printer_technology();
PrinterTechnology ptech = current_printer_technology();
bool settings_changed = false;
float dist_min = 0.f;
@ -4680,7 +4427,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "settings";
item.icon_filename = "settings.svg";
item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ;
item.sprite_id = 10;
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
@ -4722,7 +4469,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.sprite_id = 12;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
item.visibility_callback = [this]()->bool {
bool res = m_process->current_printer_technology() == ptFFF;
bool res = current_printer_technology() == ptFFF;
// turns off if changing printer technology
if (!res && m_main_toolbar.is_item_visible("layersediting") && m_main_toolbar.is_item_pressed("layersediting"))
force_main_toolbar_left_action(get_main_toolbar_item_id("layersediting"));
@ -4870,7 +4617,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
return;
auto *imgui = wxGetApp().imgui();
imgui->set_display_size((float)w, (float)h);
imgui->set_display_size(static_cast<float>(w), static_cast<float>(h));
const float font_size = 1.5f * wxGetApp().em_unit();
#if ENABLE_RETINA_GL
imgui->set_scaling(font_size, 1.0f, m_retina_helper->get_scale_factor());
@ -4878,6 +4625,10 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
imgui->set_scaling(font_size, m_canvas->GetContentScaleFactor(), 1.0f);
#endif
#if ENABLE_SCROLLABLE_LEGEND
this->request_extra_frame();
#endif // ENABLE_SCROLLABLE_LEGEND
// ensures that this canvas is current
_set_current();
}
@ -4918,8 +4669,7 @@ void GLCanvas3D::_update_camera_zoom(double zoom)
void GLCanvas3D::_refresh_if_shown_on_screen()
{
if (_is_shown_on_screen())
{
if (_is_shown_on_screen()) {
const Size& cnv_size = get_canvas_size();
_resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
@ -5304,9 +5054,6 @@ void GLCanvas3D::_render_overlays() const
_check_and_update_toolbar_icon_scale();
_render_gizmos_overlay();
#if !ENABLE_WARNING_TEXTURE_REMOVAL
_render_warning_texture();
#endif // !ENABLE_WARNING_TEXTURE_REMOVAL
// main toolbar and undoredo toolbar need to be both updated before rendering because both their sizes are needed
// to correctly place them
@ -5344,13 +5091,6 @@ void GLCanvas3D::_render_overlays() const
glsafe(::glPopMatrix());
}
#if !ENABLE_WARNING_TEXTURE_REMOVAL
void GLCanvas3D::_render_warning_texture() const
{
m_warning_texture.render(*this);
}
#endif // !ENABLE_WARNING_TEXTURE_REMOVAL
void GLCanvas3D::_render_volumes_for_picking() const
{
static const GLfloat INV_255 = 1.0f / 255.0f;
@ -6031,7 +5771,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
{
if (layerm->slices.surfaces.empty())
continue;
const PrintRegionConfig& cfg = layerm->region()->config();
const PrintRegionConfig& cfg = layerm->region().config();
if (cfg.perimeter_extruder.value == m_selected_extruder ||
cfg.infill_extruder.value == m_selected_extruder ||
cfg.solid_infill_extruder.value == m_selected_extruder ) {
@ -6054,7 +5794,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
for (const LayerRegion *layerm : layer->regions()) {
if (is_selected_separate_extruder)
{
const PrintRegionConfig& cfg = layerm->region()->config();
const PrintRegionConfig& cfg = layerm->region().config();
if (cfg.perimeter_extruder.value != m_selected_extruder ||
cfg.infill_extruder.value != m_selected_extruder ||
cfg.solid_infill_extruder.value != m_selected_extruder)
@ -6062,7 +5802,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
}
if (ctxt.has_perimeters)
_3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
volume(idx_layer, layerm->region()->config().perimeter_extruder.value, 0));
volume(idx_layer, layerm->region().config().perimeter_extruder.value, 0));
if (ctxt.has_infill) {
for (const ExtrusionEntity *ee : layerm->fills.entities) {
// fill represents infill extrusions of a single island.
@ -6071,8 +5811,8 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
_3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
volume(idx_layer,
is_solid_infill(fill->entities.front()->role()) ?
layerm->region()->config().solid_infill_extruder :
layerm->region()->config().infill_extruder,
layerm->region().config().solid_infill_extruder :
layerm->region().config().infill_extruder,
1));
}
}
@ -6297,7 +6037,7 @@ void GLCanvas3D::_load_sla_shells()
#else
v.indexed_vertex_array.load_mesh(mesh);
#endif // ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.finalize_geometry(this->m_initialized);
v.indexed_vertex_array.finalize_geometry(m_initialized);
v.shader_outside_printer_detection_enabled = outside_printer_detection_enabled;
v.composite_id.volume_id = volume_id;
v.set_instance_offset(unscale(instance.shift.x(), instance.shift.y(), 0));
@ -6347,7 +6087,6 @@ void GLCanvas3D::_update_sla_shells_outside_state()
}
}
#if ENABLE_WARNING_TEXTURE_REMOVAL
void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning)
{
_set_current();
@ -6364,24 +6103,6 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning)
}
_set_warning_notification(warning, show);
}
#else
void GLCanvas3D::_show_warning_texture_if_needed(WarningTexture::Warning warning)
{
_set_current();
bool show = false;
if (!m_volumes.empty())
show = _is_any_volume_outside();
else {
if (wxGetApp().is_editor()) {
BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box();
if (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0)
show = !test_volume.contains(paths_volume);
}
}
_set_warning_texture(warning, show);
}
#endif // ENABLE_WARNING_TEXTURE_REMOVAL
std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors)
{
@ -6405,7 +6126,6 @@ std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& col
return output;
}
#if ENABLE_WARNING_TEXTURE_REMOVAL
void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
{
enum ErrorType{
@ -6451,12 +6171,6 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
break;
}
}
#else
void GLCanvas3D::_set_warning_texture(WarningTexture::Warning warning, bool state)
{
m_warning_texture.activate(warning, state, *this);
}
#endif // !ENABLE_WARNING_TEXTURE_REMOVAL
bool GLCanvas3D::_is_any_volume_outside() const
{