Fixed conflicts after merge with dev branch

This commit is contained in:
enricoturri1966 2022-01-29 09:50:55 +01:00
commit 238516a660
178 changed files with 261670 additions and 51143 deletions

View file

@ -72,10 +72,17 @@
static constexpr const float TRACKBALLSIZE = 0.8f;
#if ENABLE_GLBEGIN_GLEND_REMOVAL
static const Slic3r::ColorRGBA DEFAULT_BG_DARK_COLOR = { 0.478f, 0.478f, 0.478f, 1.0f };
static const Slic3r::ColorRGBA DEFAULT_BG_LIGHT_COLOR = { 0.753f, 0.753f, 0.753f, 1.0f };
static const Slic3r::ColorRGBA ERROR_BG_DARK_COLOR = { 0.478f, 0.192f, 0.039f, 1.0f };
static const Slic3r::ColorRGBA ERROR_BG_LIGHT_COLOR = { 0.753f, 0.192f, 0.039f, 1.0f };
#else
static const Slic3r::ColorRGB DEFAULT_BG_DARK_COLOR = { 0.478f, 0.478f, 0.478f };
static const Slic3r::ColorRGB DEFAULT_BG_LIGHT_COLOR = { 0.753f, 0.753f, 0.753f };
static const Slic3r::ColorRGB ERROR_BG_DARK_COLOR = { 0.478f, 0.192f, 0.039f };
static const Slic3r::ColorRGB ERROR_BG_LIGHT_COLOR = { 0.753f, 0.192f, 0.039f };
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
// Number of floats
static constexpr const size_t MAX_VERTEX_BUFFER_SIZE = 131072 * 6; // 3.15MB
@ -99,49 +106,6 @@ float RetinaHelper::get_scale_factor() { return float(m_window->GetContentScaleF
#undef Convex
#endif
Size::Size()
: m_width(0)
, m_height(0)
{
}
Size::Size(int width, int height, float scale_factor)
: m_width(width)
, m_height(height)
, m_scale_factor(scale_factor)
{
}
int Size::get_width() const
{
return m_width;
}
void Size::set_width(int width)
{
m_width = width;
}
int Size::get_height() const
{
return m_height;
}
void Size::set_height(int height)
{
m_height = height;
}
int Size::get_scale_factor() const
{
return m_scale_factor;
}
void Size::set_scale_factor(int scale_factor)
{
m_scale_factor = scale_factor;
}
GLCanvas3D::LayersEditing::~LayersEditing()
{
if (m_z_texture_id != 0) {
@ -210,7 +174,7 @@ void GLCanvas3D::LayersEditing::set_enabled(bool enabled)
float GLCanvas3D::LayersEditing::s_overlay_window_width;
void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas)
{
if (!m_enabled)
return;
@ -298,8 +262,15 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
imgui.end();
const Rect& bar_rect = get_bar_rect_viewport(canvas);
#if ENABLE_GLBEGIN_GLEND_REMOVAL
m_profile.dirty = m_profile.old_bar_rect != bar_rect;
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
render_active_object_annotations(canvas, bar_rect);
render_profile(bar_rect);
#if ENABLE_GLBEGIN_GLEND_REMOVAL
m_profile.old_bar_rect = bar_rect;
m_profile.dirty = false;
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
}
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
@ -373,7 +344,7 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con
return ret;
}
void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const
void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect)
{
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height");
if (shader == nullptr)
@ -391,6 +362,34 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3
glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
// Render the color bar
#if ENABLE_GLBEGIN_GLEND_REMOVAL
if (!m_profile.background.is_initialized() || m_profile.dirty) {
m_profile.background.reset();
GLModel::Geometry init_data;
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
init_data.vertices.reserve(4 * GLModel::Geometry::vertex_stride_floats(init_data.format));
init_data.indices.reserve(6 * GLModel::Geometry::index_stride_bytes(init_data.format));
// vertices
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();
init_data.add_vertex(Vec2f(l, b), Vec2f(0.0f, 0.0f));
init_data.add_vertex(Vec2f(r, b), Vec2f(1.0f, 0.0f));
init_data.add_vertex(Vec2f(r, t), Vec2f(1.0f, 1.0f));
init_data.add_vertex(Vec2f(l, t), Vec2f(0.0f, 1.0f));
// indices
init_data.add_ushort_triangle(0, 1, 2);
init_data.add_ushort_triangle(2, 3, 0);
m_profile.background.init_from(std::move(init_data));
}
m_profile.background.render();
#else
const float l = bar_rect.get_left();
const float r = bar_rect.get_right();
const float t = bar_rect.get_top();
@ -403,12 +402,14 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3
::glTexCoord2f(1.0f, 1.0f); ::glVertex2f(r, t);
::glTexCoord2f(0.0f, 1.0f); ::glVertex2f(l, t);
glsafe(::glEnd());
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
shader->stop_using();
}
void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) const
void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect)
{
//FIXME show some kind of legend.
@ -416,9 +417,60 @@ void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) const
return;
// Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
float scale_x = bar_rect.get_width() / (float)(1.12 * m_slicing_parameters->max_layer_height);
float scale_y = bar_rect.get_height() / m_object_max_z;
float x = bar_rect.get_left() + (float)m_slicing_parameters->layer_height * scale_x;
const float scale_x = bar_rect.get_width() / float(1.12 * m_slicing_parameters->max_layer_height);
const float scale_y = bar_rect.get_height() / m_object_max_z;
#if ENABLE_GLBEGIN_GLEND_REMOVAL
// Baseline
if (!m_profile.baseline.is_initialized() || m_profile.dirty) {
m_profile.baseline.reset();
GLModel::Geometry init_data;
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT };
init_data.color = ColorRGBA::BLACK();
init_data.vertices.reserve(2 * GLModel::Geometry::vertex_stride_floats(init_data.format));
init_data.indices.reserve(2 * GLModel::Geometry::index_stride_bytes(init_data.format));
// vertices
const float x = bar_rect.get_left() + float(m_slicing_parameters->layer_height) * scale_x;
init_data.add_vertex(Vec2f(x, bar_rect.get_bottom()));
init_data.add_vertex(Vec2f(x, bar_rect.get_top()));
// indices
init_data.add_ushort_line(0, 1);
m_profile.baseline.init_from(std::move(init_data));
}
if (!m_profile.profile.is_initialized() || m_profile.dirty || m_profile.old_layer_height_profile != m_layer_height_profile) {
m_profile.old_layer_height_profile = m_layer_height_profile;
m_profile.profile.reset();
GLModel::Geometry init_data;
init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::UINT };
init_data.color = ColorRGBA::BLUE();
init_data.vertices.reserve(m_layer_height_profile.size() * GLModel::Geometry::vertex_stride_floats(init_data.format));
init_data.indices.reserve(m_layer_height_profile.size() * GLModel::Geometry::index_stride_bytes(init_data.format));
// vertices + indices
for (unsigned int i = 0; i < (unsigned int)m_layer_height_profile.size(); i += 2) {
init_data.add_vertex(Vec2f(bar_rect.get_left() + float(m_layer_height_profile[i + 1]) * scale_x,
bar_rect.get_bottom() + float(m_layer_height_profile[i]) * scale_y));
init_data.add_uint_index(i / 2);
}
m_profile.profile.init_from(std::move(init_data));
}
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader != nullptr) {
shader->start_using();
m_profile.baseline.render();
m_profile.profile.render();
shader->stop_using();
}
#else
const float x = bar_rect.get_left() + float(m_slicing_parameters->layer_height) * scale_x;
// Baseline
glsafe(::glColor3f(0.0f, 0.0f, 0.0f));
@ -433,6 +485,7 @@ void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) const
for (unsigned int i = 0; i < m_layer_height_profile.size(); i += 2)
::glVertex2f(bar_rect.get_left() + (float)m_layer_height_profile[i + 1] * scale_x, bar_rect.get_bottom() + (float)m_layer_height_profile[i] * scale_y);
glsafe(::glEnd());
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
}
void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes)
@ -750,9 +803,42 @@ void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas
static ImVec2 size(0.0f, 0.0f);
auto validate_position = [](const Vec2d& position, const GLCanvas3D& canvas, const ImVec2& wnd_size) {
auto calc_cursor_height = []() {
float ret = 16.0f;
#ifdef _WIN32
// see: https://forums.codeguru.com/showthread.php?449040-get-the-system-current-cursor-size
// this code is not perfect because it returns a maximum height equal to 31 even if the cursor bitmap shown on screen is bigger
// but at least it gives the same result as wxWidgets in the settings tabs
ICONINFO ii;
if (::GetIconInfo((HICON)GetCursor(), &ii) != 0) {
BITMAP bitmap;
::GetObject(ii.hbmMask, sizeof(BITMAP), &bitmap);
int width = bitmap.bmWidth;
int height = (ii.hbmColor == nullptr) ? bitmap.bmHeight / 2 : bitmap.bmHeight;
HDC dc = ::CreateCompatibleDC(nullptr);
if (dc != nullptr) {
if (::SelectObject(dc, ii.hbmMask) != nullptr) {
for (int i = 0; i < width; ++i) {
for (int j = 0; j < height; ++j) {
if (::GetPixel(dc, i, j) != RGB(255, 255, 255)) {
if (ret < float(j))
ret = float(j);
}
}
}
::DeleteDC(dc);
}
}
::DeleteObject(ii.hbmColor);
::DeleteObject(ii.hbmMask);
}
#endif // _WIN32
return ret;
};
const Size cnv_size = canvas.get_canvas_size();
const float x = std::clamp((float)position.x(), 0.0f, (float)cnv_size.get_width() - wnd_size.x);
const float y = std::clamp((float)position.y() + 16.0f, 0.0f, (float)cnv_size.get_height() - wnd_size.y);
const float x = std::clamp(float(position.x()), 0.0f, float(cnv_size.get_width()) - wnd_size.x);
const float y = std::clamp(float(position.y()) + calc_cursor_height(), 0.0f, float(cnv_size.get_height()) - wnd_size.y);
return Vec2f(x, y);
};
@ -793,16 +879,37 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
if (polygons.empty())
return;
#if !ENABLE_GLBEGIN_GLEND_REMOVAL
size_t triangles_count = 0;
for (const Polygon& poly : polygons) {
triangles_count += poly.points.size() - 2;
}
const size_t vertices_count = 3 * triangles_count;
#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
if (m_render_fill) {
GLModel::InitializationData fill_data;
GLModel::InitializationData::Entity entity;
entity.type = GLModel::PrimitiveType::Triangles;
GLModel::Geometry fill_data;
#if ENABLE_GLBEGIN_GLEND_REMOVAL
fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::UINT };
fill_data.color = { 0.3333f, 0.0f, 0.0f, 0.5f };
// vertices + indices
const ExPolygons polygons_union = union_ex(polygons);
unsigned int vertices_counter = 0;
for (const ExPolygon& poly : polygons_union) {
const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(poly);
for (const Vec3d& v : triangulation) {
fill_data.add_vertex((Vec3f)(v.cast<float>() + 0.0125f * Vec3f::UnitZ())); // add a small positive z to avoid z-fighting
++vertices_counter;
if (vertices_counter % 3 == 0)
fill_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
}
}
m_fill.init_from(std::move(fill_data));
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
entity.color = { 0.3333f, 0.0f, 0.0f, 0.5f };
entity.positions.reserve(vertices_count);
entity.normals.reserve(vertices_count);
@ -825,12 +932,16 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
fill_data.entities.emplace_back(entity);
m_fill.init_from(fill_data);
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
}
GLModel::InitializationData perimeter_data;
#if ENABLE_GLBEGIN_GLEND_REMOVAL
m_perimeter.init_from(polygons, 0.025f); // add a small positive z to avoid z-fighting
#else
GLModel::Geometry perimeter_data;
for (const Polygon& poly : polygons) {
GLModel::InitializationData::Entity ent;
ent.type = GLModel::PrimitiveType::LineLoop;
GLModel::Geometry::Entity ent;
ent.type = GLModel::EPrimitiveType::LineLoop;
ent.positions.reserve(poly.points.size());
ent.indices.reserve(poly.points.size());
unsigned int id_count = 0;
@ -844,6 +955,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
}
m_perimeter.init_from(perimeter_data);
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
}
void GLCanvas3D::SequentialPrintClearance::render()
@ -851,7 +963,11 @@ void GLCanvas3D::SequentialPrintClearance::render()
const ColorRGBA FILL_COLOR = { 1.0f, 0.0f, 0.0f, 0.5f };
const ColorRGBA NO_FILL_COLOR = { 1.0f, 1.0f, 1.0f, 0.75f };
#if ENABLE_GLBEGIN_GLEND_REMOVAL
GLShaderProgram* shader = wxGetApp().get_shader("flat");
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
if (shader == nullptr)
return;
@ -862,7 +978,11 @@ void GLCanvas3D::SequentialPrintClearance::render()
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
#if ENABLE_GLBEGIN_GLEND_REMOVAL
m_perimeter.set_color(m_render_fill ? FILL_COLOR : NO_FILL_COLOR);
#else
m_perimeter.set_color(-1, m_render_fill ? FILL_COLOR : NO_FILL_COLOR);
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
m_perimeter.render();
m_fill.render();
@ -1123,11 +1243,18 @@ ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state() const
void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo, int instance_idx)
{
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
if (current_printer_technology() != ptSLA)
return;
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
m_render_sla_auxiliaries = visible;
for (GLVolume* vol : m_volumes.volumes) {
#if !ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
if (vol->composite_id.object_id == 1000)
continue; // the wipe tower
#endif // !ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo)
&& (instance_idx == -1 || vol->composite_id.instance_id == instance_idx)
&& vol->composite_id.volume_id < 0)
@ -1138,9 +1265,14 @@ void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObje
void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject* mo, int instance_idx, const ModelVolume* mv)
{
for (GLVolume* vol : m_volumes.volumes) {
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
if (vol->is_wipe_tower)
vol->is_active = (visible && mo == nullptr);
#else
if (vol->composite_id.object_id == 1000) { // wipe tower
vol->is_active = (visible && mo == nullptr);
}
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
else {
if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo)
&& (instance_idx == -1 || vol->composite_id.instance_id == instance_idx)
@ -1165,6 +1297,7 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject
}
}
}
if (visible && !mo)
toggle_sla_auxiliaries_visibility(true, mo, instance_idx);
@ -1182,7 +1315,7 @@ void GLCanvas3D::update_instance_printable_state_for_object(const size_t obj_idx
ModelInstance* instance = model_object->instances[inst_idx];
for (GLVolume* volume : m_volumes.volumes) {
if ((volume->object_idx() == (int)obj_idx) && (volume->instance_idx() == inst_idx))
if (volume->object_idx() == (int)obj_idx && volume->instance_idx() == inst_idx)
volume->printable = instance->printable;
}
}
@ -1848,6 +1981,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
volume->is_modifier = !mvs->model_volume->is_model_part();
volume->set_color(color_from_model_volume(*mvs->model_volume));
// force update of render_color alpha channel
volume->set_render_color(volume->color.is_transparent());
// updates volumes transformations
volume->set_instance_transformation(mvs->model_volume->get_object()->instances[mvs->composite_id.instance_id]->get_transformation());
@ -2023,9 +2158,15 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
float depth = print->wipe_tower_data(extruders_count).depth;
float brim_width = print->wipe_tower_data(extruders_count).brim_width;
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
brim_width, m_initialized);
#else
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
brim_width, m_initialized);
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
if (volume_idx_wipe_tower_old != -1)
map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new;
}
@ -2942,6 +3083,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
mouse_up_cleanup();
m_mouse.set_start_position_3D_as_invalid();
#if ENABLE_OBJECT_MANIPULATOR_FOCUS
handle_sidebar_focus_event("", false);
#endif // ENABLE_OBJECT_MANIPULATOR_FOCUS
return;
}
@ -2949,6 +3093,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
mouse_up_cleanup();
m_mouse.set_start_position_3D_as_invalid();
#if ENABLE_OBJECT_MANIPULATOR_FOCUS
handle_sidebar_focus_event("", false);
#endif // ENABLE_OBJECT_MANIPULATOR_FOCUS
return;
}
@ -2956,6 +3103,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
mouse_up_cleanup();
m_mouse.set_start_position_3D_as_invalid();
#if ENABLE_OBJECT_MANIPULATOR_FOCUS
handle_sidebar_focus_event("", false);
#endif // ENABLE_OBJECT_MANIPULATOR_FOCUS
return;
}
@ -2963,6 +3113,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
mouse_up_cleanup();
m_mouse.set_start_position_3D_as_invalid();
#if ENABLE_OBJECT_MANIPULATOR_FOCUS
handle_sidebar_focus_event("", false);
#endif // ENABLE_OBJECT_MANIPULATOR_FOCUS
return;
}
@ -3016,6 +3169,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
#if ENABLE_OBJECT_MANIPULATOR_FOCUS
handle_sidebar_focus_event("", false);
#endif // ENABLE_OBJECT_MANIPULATOR_FOCUS
return;
}
@ -3030,15 +3186,31 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.set_move_start_threshold_position_2D_as_invalid();
}
#if ENABLE_OBJECT_MANIPULATOR_FOCUS
if (evt.ButtonDown()) {
std::string curr_sidebar_field = m_sidebar_field;
handle_sidebar_focus_event("", false);
if (boost::algorithm::istarts_with(curr_sidebar_field, "layer"))
// restore visibility of layers hints after left clicking on the 3D scene
m_sidebar_field = curr_sidebar_field;
if (wxWindow::FindFocus() != m_canvas)
// Grab keyboard focus on any mouse click event.
m_canvas->SetFocus();
}
#else
if (evt.ButtonDown() && wxWindow::FindFocus() != m_canvas)
// Grab keyboard focus on any mouse click event.
m_canvas->SetFocus();
#endif // ENABLE_OBJECT_MANIPULATOR_FOCUS
if (evt.Entering()) {
//#if defined(__WXMSW__) || defined(__linux__)
// // On Windows and Linux needs focus in order to catch key events
#if !ENABLE_OBJECT_MANIPULATOR_FOCUS
// Set focus in order to remove it from sidebar fields
#endif // !ENABLE_OBJECT_MANIPULATOR_FOCUS
if (m_canvas != nullptr) {
#if !ENABLE_OBJECT_MANIPULATOR_FOCUS
// Only set focus, if the top level window of this canvas is active.
auto p = dynamic_cast<wxWindow*>(evt.GetEventObject());
while (p->GetParent())
@ -3046,6 +3218,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
auto *top_level_wnd = dynamic_cast<wxTopLevelWindow*>(p);
if (top_level_wnd && top_level_wnd->IsActive())
m_canvas->SetFocus();
#endif // !ENABLE_OBJECT_MANIPULATOR_FOCUS
m_mouse.position = pos.cast<double>();
m_tooltip_enabled = false;
// 1) forces a frame render to ensure that m_hover_volume_idxs is updated even when the user right clicks while
@ -3478,9 +3651,15 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
model_object->invalidate_bounding_box();
}
}
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
else if (v->is_wipe_tower)
// Move a wipe tower proxy.
wipe_tower_origin = v->get_volume_offset();
#else
else if (object_idx == 1000)
// Move a wipe tower proxy.
wipe_tower_origin = v->get_volume_offset();
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
}
// Fixes flying instances
@ -3540,11 +3719,18 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
Selection::EMode selection_mode = m_selection.get_mode();
for (const GLVolume* v : m_volumes.volumes) {
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
if (v->is_wipe_tower) {
#else
int object_idx = v->object_idx();
if (object_idx == 1000) { // the wipe tower
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
Vec3d offset = v->get_volume_offset();
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset(0), offset(1), v->get_volume_rotation()(2))));
}
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
int object_idx = v->object_idx();
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
continue;
@ -3738,7 +3924,6 @@ void GLCanvas3D::update_gizmos_on_off_state()
void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool focus_on)
{
m_sidebar_field = focus_on ? opt_key : "";
if (!m_sidebar_field.empty())
m_gizmos.reset_all_states();
@ -4882,19 +5067,33 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_be
// The following is a workaround for gizmos not being taken in account when calculating the tight camera frustrum
// A better solution would ask the gizmo manager for the bounding box of the current active gizmo, if any
if (include_gizmos && m_gizmos.is_running())
{
BoundingBoxf3 sel_bb = m_selection.get_bounding_box();
Vec3d sel_bb_center = sel_bb.center();
Vec3d extend_by = sel_bb.max_size() * Vec3d::Ones();
if (include_gizmos && m_gizmos.is_running()) {
const BoundingBoxf3 sel_bb = m_selection.get_bounding_box();
const Vec3d sel_bb_center = sel_bb.center();
const Vec3d extend_by = sel_bb.max_size() * Vec3d::Ones();
bb.merge(BoundingBoxf3(sel_bb_center - extend_by, sel_bb_center + extend_by));
}
bb.merge(include_bed_model ? m_bed.extended_bounding_box() : m_bed.build_volume().bounding_volume());
const BoundingBoxf3 bed_bb = include_bed_model ? m_bed.extended_bounding_box() : m_bed.build_volume().bounding_volume();
bb.merge(bed_bb);
if (!m_main_toolbar.is_enabled())
bb.merge(m_gcode_viewer.get_max_bounding_box());
// clamp max bb size with respect to bed bb size
if (!m_picking_enabled) {
static const double max_scale_factor = 1.5;
const Vec3d bb_size = bb.size();
const Vec3d bed_bb_size = bed_bb.size();
if (bb_size.x() > max_scale_factor * bed_bb_size.x() ||
bb_size.y() > max_scale_factor * bed_bb_size.y() ||
bb_size.z() > max_scale_factor * bed_bb_size.z()) {
const Vec3d bed_bb_center = bed_bb.center();
const Vec3d extend_by = max_scale_factor * bed_bb_size;
bb = BoundingBoxf3(bed_bb_center - extend_by, bed_bb_center + extend_by);
}
}
return bb;
}
@ -5065,7 +5264,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
_update_volumes_hover_state();
}
void GLCanvas3D::_render_background() const
void GLCanvas3D::_render_background()
{
bool use_error_color = false;
if (wxGetApp().is_editor()) {
@ -5087,6 +5286,40 @@ void GLCanvas3D::_render_background() const
// Draws a bottom to top gradient over the complete screen.
glsafe(::glDisable(GL_DEPTH_TEST));
#if ENABLE_GLBEGIN_GLEND_REMOVAL
const ColorRGBA bottom_color = use_error_color ? ERROR_BG_DARK_COLOR : DEFAULT_BG_DARK_COLOR;
if (!m_background.is_initialized()) {
m_background.reset();
GLModel::Geometry init_data;
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
init_data.vertices.reserve(4 * GLModel::Geometry::vertex_stride_floats(init_data.format));
init_data.indices.reserve(6 * GLModel::Geometry::index_stride_bytes(init_data.format));
// vertices
init_data.add_vertex(Vec2f(-1.0f, -1.0f), Vec2f(0.0f, 0.0f));
init_data.add_vertex(Vec2f(1.0f, -1.0f), Vec2f(1.0f, 0.0f));
init_data.add_vertex(Vec2f(1.0f, 1.0f), Vec2f(1.0f, 1.0f));
init_data.add_vertex(Vec2f(-1.0f, 1.0f), Vec2f(0.0f, 1.0f));
// indices
init_data.add_ushort_triangle(0, 1, 2);
init_data.add_ushort_triangle(2, 3, 0);
m_background.init_from(std::move(init_data));
}
GLShaderProgram* shader = wxGetApp().get_shader("background");
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("top_color", use_error_color ? ERROR_BG_LIGHT_COLOR : DEFAULT_BG_LIGHT_COLOR);
shader->set_uniform("bottom_color", bottom_color);
m_background.render();
shader->stop_using();
}
#else
::glBegin(GL_QUADS);
::glColor3fv(use_error_color ? ERROR_BG_DARK_COLOR.data(): DEFAULT_BG_DARK_COLOR.data());
::glVertex2f(-1.0f, -1.0f);
@ -5096,6 +5329,7 @@ void GLCanvas3D::_render_background() const
::glVertex2f(1.0f, 1.0f);
::glVertex2f(-1.0f, 1.0f);
glsafe(::glEnd());
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
glsafe(::glEnable(GL_DEPTH_TEST));
@ -5181,6 +5415,9 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
m_volumes.set_show_sinking_contours(! m_gizmos.is_hiding_instances());
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
m_volumes.set_show_non_manifold_edges(!m_gizmos.is_hiding_instances() && m_gizmos.get_current_type() != GLGizmosManager::Simplify);
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
if (shader != nullptr) {
@ -5211,7 +5448,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
// before transparent objects are rendered. Otherwise they would not be
// visible when inside modifier meshes etc.
{
const GLGizmosManager& gm = get_gizmos_manager();
GLGizmosManager& gm = get_gizmos_manager();
// GLGizmosManager::EType type = gm.get_current_type();
if (dynamic_cast<GLGizmoPainterBase*>(gm.get_current())) {
shader->stop_using();
@ -5238,7 +5475,7 @@ void GLCanvas3D::_render_gcode()
m_gcode_viewer.render();
}
void GLCanvas3D::_render_selection() const
void GLCanvas3D::_render_selection()
{
float scale_factor = 1.0;
#if ENABLE_RETINA_GL
@ -5269,7 +5506,7 @@ void GLCanvas3D::_render_sequential_clearance()
}
#if ENABLE_RENDER_SELECTION_CENTER
void GLCanvas3D::_render_selection_center() const
void GLCanvas3D::_render_selection_center()
{
m_selection.render_center(m_gizmos.is_dragging());
}
@ -5513,28 +5750,78 @@ void GLCanvas3D::_render_view_toolbar() const
}
#if ENABLE_SHOW_CAMERA_TARGET
void GLCanvas3D::_render_camera_target() const
void GLCanvas3D::_render_camera_target()
{
double half_length = 5.0;
static const double half_length = 5.0;
glsafe(::glDisable(GL_DEPTH_TEST));
glsafe(::glLineWidth(2.0f));
#if ENABLE_GLBEGIN_GLEND_REMOVAL
const Vec3d& target = wxGetApp().plater()->get_camera().get_target();
bool target_changed = !m_camera_target.target.isApprox(target);
m_camera_target.target = target;
for (int i = 0; i < 3; ++i) {
if (!m_camera_target.axis[i].is_initialized() || target_changed) {
m_camera_target.axis[i].reset();
GLModel::InitializationData init_data;
GLModel::InitializationData::Entity entity;
entity.type = GLModel::PrimitiveType::Lines;
entity.positions.reserve(2);
if (i == X) {
entity.positions.emplace_back(target.x() - half_length, target.y(), target.z());
entity.positions.emplace_back(target.x() + half_length, target.y(), target.z());
}
else if (i == Y) {
entity.positions.emplace_back(target.x(), target.y() - half_length, target.z());
entity.positions.emplace_back(target.x(), target.y() + half_length, target.z());
}
else {
entity.positions.emplace_back(target.x(), target.y(), target.z() - half_length);
entity.positions.emplace_back(target.x(), target.y(), target.z() + half_length);
}
entity.normals.reserve(2);
for (size_t j = 0; j < 2; ++j) {
entity.normals.emplace_back(Vec3f::UnitZ());
}
entity.indices.reserve(2);
entity.indices.emplace_back(0);
entity.indices.emplace_back(1);
init_data.entities.emplace_back(entity);
m_camera_target.axis[i].init_from(init_data);
m_camera_target.axis[i].set_color(-1, (i == X) ? ColorRGBA::X() : (i == Y) ? ColorRGBA::Y() : ColorRGBA::Z());
}
}
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader != nullptr) {
shader->start_using();
for (int i = 0; i < 3; ++i) {
m_camera_target.axis[i].render();
}
shader->stop_using();
}
#else
::glBegin(GL_LINES);
const Vec3d& target = m_camera.get_target();
const Vec3d& target = wxGetApp().plater()->get_camera().get_target();
// draw line for x axis
::glColor3f(1.0f, 0.0f, 0.0f);
::glVertex3d(target(0) - half_length, target(1), target(2));
::glVertex3d(target(0) + half_length, target(1), target(2));
::glVertex3d(target.x() - half_length, target.y(), target.z());
::glVertex3d(target.x() + half_length, target.y(), target.z());
// draw line for y axis
::glColor3f(0.0f, 1.0f, 0.0f);
::glVertex3d(target(0), target(1) - half_length, target(2));
::glVertex3d(target(0), target(1) + half_length, target(2));
::glVertex3d(target.x(), target.y() - half_length, target.z());
::glVertex3d(target.x(), target.y() + half_length, target.z());
// draw line for z axis
::glColor3f(0.0f, 0.0f, 1.0f);
::glVertex3d(target(0), target(1), target(2) - half_length);
::glVertex3d(target(0), target(1), target(2) + half_length);
::glVertex3d(target.x(), target.y(), target.z() - half_length);
::glVertex3d(target.x(), target.y(), target.z() + half_length);
glsafe(::glEnd());
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
}
#endif // ENABLE_SHOW_CAMERA_TARGET
@ -5656,7 +5943,7 @@ void GLCanvas3D::_render_sla_slices()
}
}
void GLCanvas3D::_render_selection_sidebar_hints() const
void GLCanvas3D::_render_selection_sidebar_hints()
{
m_selection.render_sidebar_hints(m_sidebar_field);
}
@ -6146,10 +6433,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info();
// Remove empty volumes from the newly added volumes.
m_volumes.volumes.erase(
std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(),
[](const GLVolume *volume) { return volume->empty(); }),
m_volumes.volumes.end());
{
for (auto ptr_it = m_volumes.volumes.begin() + volumes_cnt_initial; ptr_it != m_volumes.volumes.end(); ++ptr_it)
if ((*ptr_it)->empty()) {
delete *ptr_it;
*ptr_it = nullptr;
}
m_volumes.volumes.erase(std::remove(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), nullptr), m_volumes.volumes.end());
}
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) {
GLVolume* v = m_volumes.volumes[i];
v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box());
@ -6307,10 +6598,14 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info();
// Remove empty volumes from the newly added volumes.
m_volumes.volumes.erase(
std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(),
[](const GLVolume *volume) { return volume->empty(); }),
m_volumes.volumes.end());
{
for (auto ptr_it = m_volumes.volumes.begin() + volumes_cnt_initial; ptr_it != m_volumes.volumes.end(); ++ptr_it)
if ((*ptr_it)->empty()) {
delete *ptr_it;
*ptr_it = nullptr;
}
m_volumes.volumes.erase(std::remove(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), nullptr), m_volumes.volumes.end());
}
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) {
GLVolume* v = m_volumes.volumes[i];
v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box());