SPE-2506 - Fixed rendering of sequential print clearance contours when using multiple beds

This commit is contained in:
enricoturri1966 2024-11-09 11:32:17 +01:00 committed by Lukas Matena
parent bbdd2e9d07
commit 0bd37e6b08
3 changed files with 52 additions and 24 deletions

View File

@ -108,6 +108,8 @@ void GLCanvas3D::select_bed(int i)
if (i == old_bed || i == -1)
return;
wxGetApp().plater()->canvas3D()->m_process->stop();
m_sequential_print_clearance.m_evaluating = true;
reset_sequential_print_clearance();
// The stop call above schedules some events that would be processed after the switch.
// Among else, on_process_completed would be called, which would stop slicing of
@ -908,6 +910,8 @@ void GLCanvas3D::SequentialPrintClearance::set_contours(const ContoursList& cont
if (contours.empty())
return;
const Vec3d bed_offset = generate_fill ? s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()) : Vec3d::Zero();
if (generate_fill) {
GLModel::Geometry fill_data;
fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
@ -921,7 +925,7 @@ void GLCanvas3D::SequentialPrintClearance::set_contours(const ContoursList& cont
fill_data.reserve_vertices(fill_data.vertices_count() + triangulation.size());
fill_data.reserve_indices(fill_data.indices_count() + triangulation.size());
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
fill_data.add_vertex((Vec3f)((bed_offset + 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_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
@ -930,6 +934,8 @@ void GLCanvas3D::SequentialPrintClearance::set_contours(const ContoursList& cont
m_fill.init_from(std::move(fill_data));
}
const Transform3d bed_transform = Geometry::translation_transform(bed_offset);
for (size_t i = 0; i < contours.contours.size(); ++i) {
GLModel& model = m_contours.emplace_back(GLModel());
model.init_from(contours.contours[i], 0.025f); // add a small positive z to avoid z-fighting
@ -938,14 +944,14 @@ void GLCanvas3D::SequentialPrintClearance::set_contours(const ContoursList& cont
if (contours.trafos.has_value()) {
// create the requested instances
for (const auto& instance : *contours.trafos) {
m_instances.emplace_back(instance.first, instance.second);
m_instances.emplace_back(instance.first, bed_transform * instance.second);
}
}
else {
// no instances have been specified
// create one instance for every polygon
for (size_t i = 0; i < contours.contours.size(); ++i) {
m_instances.emplace_back(i, Transform3f::Identity());
m_instances.emplace_back(i, bed_transform);
}
}
}
@ -963,9 +969,9 @@ void GLCanvas3D::SequentialPrintClearance::update_instances_trafos(const std::ve
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 };
const ColorRGBA NO_FILL_EVALUATING_COLOR = { 1.0f, 1.0f, 0.0f, 1.0f };
static const ColorRGBA FILL_COLOR = { 1.0f, 0.0f, 0.0f, 0.5f };
static const ColorRGBA NO_FILL_COLOR = { 1.0f, 1.0f, 1.0f, 0.75f };
static const ColorRGBA NO_FILL_EVALUATING_COLOR = { 1.0f, 1.0f, 0.0f, 1.0f };
if (m_contours.empty() || m_instances.empty())
return;
@ -1013,10 +1019,13 @@ void GLCanvas3D::SequentialPrintClearance::render()
glsafe(::glLineWidth(2.0f));
#endif // !SLIC3R_OPENGL_ES
const ColorRGBA color = (!m_evaluating && !m_dragging && m_fill.is_initialized()) ? FILL_COLOR :
m_evaluating ? NO_FILL_EVALUATING_COLOR : NO_FILL_COLOR;
for (const auto& [id, trafo] : m_instances) {
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo);
assert(id < m_contours.size());
m_contours[id].set_color((!m_evaluating && m_fill.is_initialized()) ? FILL_COLOR : m_evaluating ? NO_FILL_EVALUATING_COLOR : NO_FILL_COLOR);
m_contours[id].set_color(color);
m_contours[id].render();
}
@ -3545,7 +3554,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
c == GLGizmosManager::EType::Scale ||
c == GLGizmosManager::EType::Rotate) {
show_sinking_contours();
if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects)
if (_is_sequential_print_enabled())
update_sequential_clearance(true);
}
}
@ -3705,7 +3714,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_selection.setup_cache();
if (!evt.CmdDown())
m_mouse.drag.start_position_3D = m_mouse.scene_position;
m_sequential_print_clearance_first_displacement = true;
m_sequential_print_clearance.m_first_displacement = true;
if (_is_sequential_print_enabled())
update_sequential_clearance(true);
m_sequential_print_clearance.start_dragging();
}
}
@ -3755,7 +3766,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
TransformationType trafo_type;
trafo_type.set_relative();
m_selection.translate(cur_pos - m_mouse.drag.start_position_3D, trafo_type);
if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects)
if (_is_sequential_print_enabled())
update_sequential_clearance(false);
wxGetApp().obj_manipul()->set_dirty();
m_dirty = true;
@ -3834,6 +3845,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
else if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) {
m_mouse.position = pos.cast<double>();
if (evt.LeftUp() && m_sequential_print_clearance.is_dragging())
m_sequential_print_clearance.stop_dragging();
if (m_layers_editing.state != LayersEditing::Unknown) {
m_layers_editing.state = LayersEditing::Unknown;
_stop_timer();
@ -3844,7 +3858,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
s_virtual_bed_timer.Stop();
do_move(L("Move Object"));
wxGetApp().obj_manipul()->set_dirty();
m_sequential_print_clearance.stop_dragging();
// Let the plater know that the dragging finished, so a delayed refresh
// of the scene with the background processing data should be performed.
post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
@ -4094,7 +4107,7 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
post_event(SimpleEvent(EVT_GLCANVAS_WIPETOWER_TOUCHED));
}
if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects) {
if (_is_sequential_print_enabled()) {
update_sequential_clearance(true);
m_sequential_print_clearance.m_evaluating = true;
}
@ -4192,7 +4205,7 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
if (!done.empty())
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_ROTATED));
if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects) {
if (_is_sequential_print_enabled()) {
update_sequential_clearance(true);
m_sequential_print_clearance.m_evaluating = true;
}
@ -4269,7 +4282,7 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
if (!done.empty())
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_SCALED));
if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects) {
if (_is_sequential_print_enabled()) {
update_sequential_clearance(true);
m_sequential_print_clearance.m_evaluating = true;
}
@ -4529,7 +4542,7 @@ void GLCanvas3D::mouse_up_cleanup()
void GLCanvas3D::update_sequential_clearance(bool force_contours_generation)
{
if (current_printer_technology() != ptFFF || !fff_print()->config().complete_objects)
if (!_is_sequential_print_enabled())
return;
if (m_layers_editing.is_enabled())
@ -4591,7 +4604,7 @@ void GLCanvas3D::update_sequential_clearance(bool force_contours_generation)
// calculates objects 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid())
// this is done only the first time this method is called while moving the mouse,
// the results are then cached for following displacements
if (force_contours_generation || m_sequential_print_clearance_first_displacement) {
if (force_contours_generation || m_sequential_print_clearance.m_first_displacement) {
m_sequential_print_clearance.m_evaluating = false;
m_sequential_print_clearance.m_hulls_2d_cache.clear();
const float shrink_factor = static_cast<float>(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON));
@ -4640,7 +4653,7 @@ void GLCanvas3D::update_sequential_clearance(bool force_contours_generation)
}
set_sequential_print_clearance_contours(contours, false);
m_sequential_print_clearance_first_displacement = false;
m_sequential_print_clearance.m_first_displacement = false;
}
else {
if (!m_sequential_print_clearance.empty()) {
@ -6121,7 +6134,7 @@ void GLCanvas3D::_render_selection()
void GLCanvas3D::_render_sequential_clearance()
{
if (current_printer_technology() != ptFFF || !fff_print()->config().complete_objects)
if (!_is_sequential_print_enabled())
return;
if (m_layers_editing.is_enabled())
@ -6246,10 +6259,8 @@ void GLCanvas3D::_render_overlays()
if (m_layers_editing.last_object_id >= 0 && m_layers_editing.object_max_z() > 0.0f)
m_layers_editing.render_overlay(*this);
const ConfigOptionBool* opt = dynamic_cast<const ConfigOptionBool*>(m_config->option("complete_objects"));
bool sequential_print = opt != nullptr && opt->value;
std::vector<const ModelInstance*> sorted_instances;
if (sequential_print) {
if (_is_sequential_print_enabled()) {
for (ModelObject* model_object : m_model->objects)
for (ModelInstance* model_instance : model_object->instances) {
sorted_instances.emplace_back(model_instance);
@ -7065,6 +7076,11 @@ std::pair<bool, const GLVolume*> GLCanvas3D::_is_any_volume_outside() const
return std::make_pair(false, nullptr);
}
bool GLCanvas3D::_is_sequential_print_enabled() const
{
return current_printer_technology() == ptFFF && fff_print()->config().complete_objects;
}
void GLCanvas3D::_update_selection_from_hover()
{
bool ctrl_pressed = wxGetKeyState(WXK_CONTROL);

View File

@ -628,6 +628,7 @@ private:
std::vector<std::pair<size_t, Transform3d>> m_instances;
bool m_evaluating{ false };
bool m_dragging{ false };
bool m_first_displacement{ true };
std::vector<std::pair<Pointf3s, Transform3d>> m_hulls_2d_cache;
@ -645,7 +646,6 @@ private:
};
SequentialPrintClearance m_sequential_print_clearance;
bool m_sequential_print_clearance_first_displacement{ true };
struct ToolbarHighlighter
{
@ -990,7 +990,7 @@ public:
void reset_sequential_print_clearance() {
m_sequential_print_clearance.m_evaluating = false;
if (m_sequential_print_clearance.is_dragging())
m_sequential_print_clearance_first_displacement = true;
m_sequential_print_clearance.m_first_displacement = true;
else
m_sequential_print_clearance.set_contours(ContoursList(), false);
set_as_dirty();
@ -999,6 +999,8 @@ public:
void set_sequential_print_clearance_contours(const ContoursList& contours, bool generate_fill) {
m_sequential_print_clearance.set_contours(contours, generate_fill);
if (generate_fill)
m_sequential_print_clearance.m_evaluating = false;
set_as_dirty();
request_extra_frame();
}
@ -1117,6 +1119,7 @@ private:
void _set_warning_notification(EWarning warning, bool state);
std::pair<bool, const GLVolume*> _is_any_volume_outside() const;
bool _is_sequential_print_enabled() const;
// updates the selection from the content of m_hover_volume_idxs
void _update_selection_from_hover();

View File

@ -2310,8 +2310,17 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
}
std::vector<std::string> warnings;
std::string err = background_process.validate(&warnings);
if (!err.empty())
if (!err.empty()) {
if (s_multiple_beds.get_number_of_beds() > 1 && printer_technology == ptFFF) {
// user changed bed seletion,
// sequential print clearance contours were changed too
GLCanvas3D* canvas = view3D->get_canvas3d();
GLCanvas3D::ContoursList contours;
contours.contours = background_process.fff_print()->get_sequential_print_clearance_contours();
canvas->set_sequential_print_clearance_contours(contours, true);
}
return return_state;
}
}
if (! this->delayed_error_message.empty())