From 22f04ca46e928981b158bcc80de1e5ceefd637de Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 21 Jul 2021 15:30:57 +0200 Subject: [PATCH 1/9] Tech ENABLE_SINKING_CONTOURS -> 1st installment --- src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/3DScene.cpp | 200 ++++++++++++++++++++++++++++++++- src/slic3r/GUI/3DScene.hpp | 32 +++++- src/slic3r/GUI/GLCanvas3D.cpp | 11 ++ src/slic3r/GUI/Plater.cpp | 1 + src/slic3r/GUI/Plater.hpp | 1 + src/slic3r/GUI/Selection.cpp | 66 +++++++---- 7 files changed, 286 insertions(+), 27 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 716e61a60..b83f7638b 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -66,6 +66,8 @@ // Enable to push object instances under the bed #define ENABLE_ALLOW_NEGATIVE_Z (1 && ENABLE_2_4_0_ALPHA0) #define DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA (1 && ENABLE_ALLOW_NEGATIVE_Z) +// Enable drawing contours, at cut level, for sinking volumes +#define ENABLE_SINKING_CONTOURS (1 && ENABLE_ALLOW_NEGATIVE_Z) // Enable delayed rendering of transparent volumes #define ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING (1 && ENABLE_2_4_0_ALPHA0) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index fb464ce02..7e5b2c056 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -9,9 +9,9 @@ #include "3DScene.hpp" #include "GLShader.hpp" #include "GUI_App.hpp" -#if ENABLE_ENVIRONMENT_MAP +#if ENABLE_ENVIRONMENT_MAP || ENABLE_SINKING_CONTOURS #include "Plater.hpp" -#endif // ENABLE_ENVIRONMENT_MAP +#endif // ENABLE_ENVIRONMENT_MAP || ENABLE_SINKING_CONTOURS #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/ExtrusionEntityCollection.hpp" @@ -286,6 +286,117 @@ void GLIndexedVertexArray::render( glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } +#if ENABLE_SINKING_CONTOURS +#define ALG_SLICE_MESH 1 +#define ALG_SLICE_MESHEX 2 +#define ALG_SLICE ALG_SLICE_MESH +void GLVolume::SinkingContours::update() +{ + if (m_parent.is_sinking() && !m_parent.is_below_printbed()) { + const BoundingBoxf3& box = m_parent.transformed_convex_hull_bounding_box(); + if (!m_old_box.size().isApprox(box.size()) || m_old_box.min.z() != box.min.z()) { + m_old_box = box; + m_shift = Vec3d::Zero(); + + const TriangleMesh& mesh = GUI::wxGetApp().plater()->model().objects[m_parent.object_idx()]->volumes[m_parent.volume_idx()]->mesh(); + assert(mesh.has_shared_vertices()); + +#if ALG_SLICE == ALG_SLICE_MESH + MeshSlicingParams slicing_params; + slicing_params.trafo = m_parent.world_matrix(); + std::vector list_of_polys = slice_mesh(mesh.its, std::vector{ 0.0f }, slicing_params); + + auto append_polygon = [this](const Polygon& polygon, GUI::GLModel::InitializationData& data) { + if (!polygon.empty()) { + GUI::GLModel::InitializationData::Entity entity; + entity.type = GUI::GLModel::PrimitiveType::LineLoop; + entity.color[0] = 1.0f - m_parent.render_color[0]; + entity.color[1] = 1.0f - m_parent.render_color[1]; + entity.color[2] = 1.0f - m_parent.render_color[2]; + entity.color[3] = m_parent.render_color[3]; + // contour + entity.positions.reserve(polygon.size() + 1); + entity.indices.reserve(polygon.size() + 1); + unsigned int id = 0; + for (const Point& p : polygon) { + entity.positions.emplace_back(unscale(p.x(), p.y(), 0.0).cast()); + entity.indices.emplace_back(id++); + } + data.entities.emplace_back(entity); + } + }; + + m_model.reset(); + GUI::GLModel::InitializationData init_data; + for (const Polygons& polygons : list_of_polys) { + for (const Polygon& polygon : polygons) { + // contour + append_polygon(polygon, init_data); + } + } +#else + MeshSlicingParamsEx slicing_params; + slicing_params.trafo = m_parent.world_matrix(); + std::vector list_of_expolys = slice_mesh_ex(mesh.its, std::vector{ 0.0f }, slicing_params); + + auto append_polygon = [this](const Polygon& polygon, GUI::GLModel::InitializationData& data) { + if (!polygon.empty()) { + GUI::GLModel::InitializationData::Entity entity; + entity.type = GUI::GLModel::PrimitiveType::LineLoop; + entity.color[0] = 1.0f - m_parent.render_color[0]; + entity.color[1] = 1.0f - m_parent.render_color[1]; + entity.color[2] = 1.0f - m_parent.render_color[2]; + entity.color[3] = m_parent.render_color[3]; + // contour + entity.positions.reserve(polygon.size() + 1); + entity.indices.reserve(polygon.size() + 1); + unsigned int id = 0; + for (const Point& p : polygon) { + entity.positions.emplace_back(unscale(p.x(), p.y(), 0.0).cast()); + entity.indices.emplace_back(id++); + } + data.entities.emplace_back(entity); + } + }; + + m_model.reset(); + GUI::GLModel::InitializationData init_data; + for (const ExPolygons& polygons : list_of_expolys) { + for (const ExPolygon& polygon : polygons) { + // contour + append_polygon(polygon.contour, init_data); + // holes + for (const Polygon& hole : polygon.holes) { + append_polygon(hole, init_data); + } + } + } +#endif // ALG_SLICE == ALG_SLICE_MESH + + if (!init_data.entities.empty()) + m_model.init_from(init_data); + } + else + m_shift = box.center() - m_old_box.center(); + } + else + m_model.reset(); +} + +void GLVolume::SinkingContours::set_color(const std::array& color) +{ + m_model.set_color(-1, { 1.0f - color[0], 1.0f - color[1], 1.0f - color[2], color[3] }); +} + +void GLVolume::SinkingContours::render() const +{ + glsafe(::glPushMatrix()); + glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z())); + m_model.render(); + glsafe(::glPopMatrix()); +} +#endif // ENABLE_SINKING_CONTOURS + const std::array GLVolume::SELECTED_COLOR = { 0.0f, 1.0f, 0.0f, 1.0f }; const std::array GLVolume::HOVER_SELECT_COLOR = { 0.4f, 0.9f, 0.1f, 1.0f }; const std::array GLVolume::HOVER_DESELECT_COLOR = { 1.0f, 0.75f, 0.75f, 1.0f }; @@ -306,6 +417,9 @@ GLVolume::GLVolume(float r, float g, float b, float a) : m_transformed_bounding_box_dirty(true) , m_sla_shift_z(0.0) , m_transformed_convex_hull_bounding_box_dirty(true) +#if ENABLE_SINKING_CONTOURS + , m_sinking_contours(*this) +#endif // ENABLE_SINKING_CONTOURS // geometry_id == 0 -> invalid , geometry_id(std::pair(0, 0)) , extruder_id(0) @@ -537,6 +651,23 @@ bool GLVolume::is_below_printbed() const { return transformed_convex_hull_bounding_box().max(2) < 0.0; } + +#if ENABLE_SINKING_CONTOURS +void GLVolume::update_sinking_contours() +{ + m_sinking_contours.update(); +} + +void GLVolume::update_sinking_contours_color() +{ + m_sinking_contours.set_color(render_color); +} + +void GLVolume::render_sinking_contours() +{ + m_sinking_contours.render(); +} +#endif // ENABLE_SINKING_CONTOURS #endif // ENABLE_ALLOW_NEGATIVE_Z std::vector GLVolumeCollection::load_object( @@ -774,6 +905,70 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab if (disable_cullface) glsafe(::glDisable(GL_CULL_FACE)); +#if ENABLE_SINKING_CONTOURS + GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func); + for (GLVolumeWithIdAndZ& volume : to_render) { + volume.first->set_render_color(); + + // render sinking contours of non-hovered volumes + if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover == GLVolume::HS_None) { + shader->stop_using(); + glsafe(::glLineWidth(5.0f)); + volume.first->update_sinking_contours_color(); + volume.first->render_sinking_contours(); + shader->start_using(); + } + + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + + shader->set_uniform("uniform_color", volume.first->render_color); + shader->set_uniform("z_range", m_z_range, 2); + shader->set_uniform("clipping_plane", m_clipping_plane, 4); + shader->set_uniform("print_box.min", m_print_box_min, 3); + shader->set_uniform("print_box.max", m_print_box_max, 3); + shader->set_uniform("print_box.actived", volume.first->shader_outside_printer_detection_enabled); + shader->set_uniform("print_box.volume_world_matrix", volume.first->world_matrix()); + shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower); + shader->set_uniform("slope.volume_world_normal_matrix", static_cast(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast())); + shader->set_uniform("slope.normal_z", m_slope.normal_z); + +#if ENABLE_ENVIRONMENT_MAP + unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id(); + bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get("use_environment_map") == "1"; + shader->set_uniform("use_environment_tex", use_environment_texture); + if (use_environment_texture) + glsafe(::glBindTexture(GL_TEXTURE_2D, environment_texture_id)); +#endif // ENABLE_ENVIRONMENT_MAP + glcheck(); + + volume.first->render(); + +#if ENABLE_ENVIRONMENT_MAP + if (use_environment_texture) + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); +#endif // ENABLE_ENVIRONMENT_MAP + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + } + + for (GLVolumeWithIdAndZ& volume : to_render) { + // render sinking contours of hovered volumes + if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover != GLVolume::HS_None) { + shader->stop_using(); + glsafe(::glLineWidth(5.0f)); + glsafe(::glDisable(GL_DEPTH_TEST)); + volume.first->update_sinking_contours_color(); + volume.first->render_sinking_contours(); + glsafe(::glEnable(GL_DEPTH_TEST)); + shader->start_using(); + } + } +#else glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); @@ -813,6 +1008,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); +#endif // ENABLE_SINKING_CONTOURS if (disable_cullface) glsafe(::glEnable(GL_CULL_FACE)); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 217d39746..36ea73a62 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -8,6 +8,10 @@ #include "libslic3r/Utils.hpp" #include "libslic3r/Geometry.hpp" +#if ENABLE_SINKING_CONTOURS +#include "GLModel.hpp" +#endif // ENABLE_SINKING_CONTOURS + #include #define HAS_GLSAFE @@ -250,6 +254,9 @@ public: enum EHoverState : unsigned char { HS_None, +#if ENABLE_SINKING_CONTOURS + HS_Hover, +#endif // ENABLE_SINKING_CONTOURS HS_Select, HS_Deselect }; @@ -262,7 +269,7 @@ private: Geometry::Transformation m_volume_transformation; // Shift in z required by sla supports+pad - double m_sla_shift_z; + double m_sla_shift_z; // Bounding box of this volume, in unscaled coordinates. BoundingBoxf3 m_transformed_bounding_box; // Whether or not is needed to recalculate the transformed bounding box. @@ -274,6 +281,24 @@ private: // Whether or not is needed to recalculate the transformed convex hull bounding box. bool m_transformed_convex_hull_bounding_box_dirty; +#if ENABLE_SINKING_CONTOURS + class SinkingContours + { + GLVolume& m_parent; + GUI::GLModel m_model; + BoundingBoxf3 m_old_box; + Vec3d m_shift{ Vec3d::Zero() }; + + public: + SinkingContours(GLVolume& volume) : m_parent(volume) {} + void update(); + void set_color(const std::array& color); + void render() const; + }; + + SinkingContours m_sinking_contours; +#endif // ENABLE_SINKING_CONTOURS + public: // Color of the triangles / quads held by this volume. std::array color; @@ -462,6 +487,11 @@ public: #if ENABLE_ALLOW_NEGATIVE_Z bool is_sinking() const; bool is_below_printbed() const; +#if ENABLE_SINKING_CONTOURS + void update_sinking_contours(); + void update_sinking_contours_color(); + void render_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS #endif // ENABLE_ALLOW_NEGATIVE_Z // Return an estimate of the memory consumed by this class. diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5be2fc7ad..33ea49c9b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2063,6 +2063,12 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re m_gizmos.update_data(); m_gizmos.refresh_on_off_state(); +#if ENABLE_SINKING_CONTOURS + for (GLVolume* v : m_volumes.volumes) { + v->update_sinking_contours(); + } +#endif // ENABLE_SINKING_CONTOURS + // Update the toolbar if (update_object_list) post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); @@ -5639,6 +5645,11 @@ void GLCanvas3D::_update_volumes_hover_state() } } } +#if ENABLE_SINKING_CONTOURS + else if (volume.selected) + volume.hover = GLVolume::HS_Hover; +#endif // ENABLE_SINKING_CONTOURS + } } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 55c7f371b..e42a10d61 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4750,6 +4750,7 @@ void Plater::render_project_state_debug_window() const { p->render_project_state #endif // ENABLE_PROJECT_DIRTY_STATE Sidebar& Plater::sidebar() { return *p->sidebar; } +const Model& Plater::model() const { return p->model; } Model& Plater::model() { return p->model; } const Print& Plater::fff_print() const { return p->fff_print; } Print& Plater::fff_print() { return p->fff_print; } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index fc4001ba5..d4d774efe 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -149,6 +149,7 @@ public: #endif // ENABLE_PROJECT_DIRTY_STATE Sidebar& sidebar(); + const Model& model() const; Model& model(); const Print& fff_print() const; Print& fff_print(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index f2e879605..834ec69d7 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -676,6 +676,9 @@ void Selection::translate(const Vec3d& displacement, bool local) translation_type = Volume; } } +#if ENABLE_SINKING_CONTOURS + v.update_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS } #if !DISABLE_INSTANCES_SYNCH @@ -701,15 +704,18 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ int rot_axis_max = 0; if (rotation.isApprox(Vec3d::Zero())) { for (unsigned int i : m_list) { - GLVolume &volume = *(*m_volumes)[i]; + GLVolume &v = *(*m_volumes)[i]; if (m_mode == Instance) { - volume.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation()); - volume.set_instance_offset(m_cache.volumes_data[i].get_instance_position()); + v.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation()); + v.set_instance_offset(m_cache.volumes_data[i].get_instance_position()); } else if (m_mode == Volume) { - volume.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation()); - volume.set_volume_offset(m_cache.volumes_data[i].get_volume_position()); + v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation()); + v.set_volume_offset(m_cache.volumes_data[i].get_volume_position()); } +#if ENABLE_SINKING_CONTOURS + v.update_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS } } else { // this is not the wipe tower @@ -749,22 +755,22 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ }; for (unsigned int i : m_list) { - GLVolume &volume = *(*m_volumes)[i]; + GLVolume &v = *(*m_volumes)[i]; if (is_single_full_instance()) - rotate_instance(volume, i); + rotate_instance(v, i); else if (is_single_volume() || is_single_modifier()) { if (transformation_type.independent()) - volume.set_volume_rotation(volume.get_volume_rotation() + rotation); + v.set_volume_rotation(v.get_volume_rotation() + rotation); else { const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); const Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); - volume.set_volume_rotation(new_rotation); + v.set_volume_rotation(new_rotation); } } else { if (m_mode == Instance) - rotate_instance(volume, i); + rotate_instance(v, i); else if (m_mode == Volume) { // extracts rotations from the composed transformation Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); @@ -772,11 +778,14 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ if (transformation_type.joint()) { const Vec3d local_pivot = m_cache.volumes_data[i].get_instance_full_matrix().inverse() * m_cache.dragging_center; const Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() - local_pivot); - volume.set_volume_offset(local_pivot + offset); + v.set_volume_offset(local_pivot + offset); } - volume.set_volume_rotation(new_rotation); + v.set_volume_rotation(new_rotation); } } +#if ENABLE_SINKING_CONTOURS + v.update_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS } } @@ -821,6 +830,9 @@ void Selection::flattening_rotate(const Vec3d& normal) // Additional rotation to align tnormal with the down vector in the world coordinate space. auto extra_rotation = Eigen::Quaterniond().setFromTwoVectors(tnormal, - Vec3d::UnitZ()); v.set_instance_rotation(Geometry::extract_euler_angles(extra_rotation.toRotationMatrix() * m_cache.volumes_data[i].get_instance_rotation_matrix())); +#if ENABLE_SINKING_CONTOURS + v.update_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS } #if !DISABLE_INSTANCES_SYNCH @@ -846,12 +858,12 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type #endif // ENABLE_ALLOW_NEGATIVE_Z for (unsigned int i : m_list) { - GLVolume &volume = *(*m_volumes)[i]; + GLVolume &v = *(*m_volumes)[i]; #if ENABLE_ALLOW_NEGATIVE_Z #if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA if (!is_sla) #endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA - is_any_volume_sinking |= !volume.is_modifier && std::find(m_cache.sinking_volumes.begin(), m_cache.sinking_volumes.end(), i) != m_cache.sinking_volumes.end(); + is_any_volume_sinking |= !v.is_modifier && std::find(m_cache.sinking_volumes.begin(), m_cache.sinking_volumes.end(), i) != m_cache.sinking_volumes.end(); #endif // ENABLE_ALLOW_NEGATIVE_Z if (is_single_full_instance()) { if (transformation_type.relative()) { @@ -860,23 +872,23 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type // extracts scaling factors from the composed transformation Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); if (transformation_type.joint()) - volume.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); + v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); - volume.set_instance_scaling_factor(new_scale); + v.set_instance_scaling_factor(new_scale); } else { if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) { // Non-uniform scaling. Transform the scaling factors into the local coordinate system. // This is only possible, if the instance rotation is mulitples of ninety degrees. - assert(Geometry::is_rotation_ninety_degrees(volume.get_instance_rotation())); - volume.set_instance_scaling_factor((volume.get_instance_transformation().get_matrix(true, false, true, true).matrix().block<3, 3>(0, 0).transpose() * scale).cwiseAbs()); + assert(Geometry::is_rotation_ninety_degrees(v.get_instance_rotation())); + v.set_instance_scaling_factor((v.get_instance_transformation().get_matrix(true, false, true, true).matrix().block<3, 3>(0, 0).transpose() * scale).cwiseAbs()); } else - volume.set_instance_scaling_factor(scale); + v.set_instance_scaling_factor(scale); } } else if (is_single_volume() || is_single_modifier()) - volume.set_volume_scaling_factor(scale); + v.set_volume_scaling_factor(scale); else { Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale); if (m_mode == Instance) { @@ -884,9 +896,9 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type // extracts scaling factors from the composed transformation Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); if (transformation_type.joint()) - volume.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); + v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); - volume.set_instance_scaling_factor(new_scale); + v.set_instance_scaling_factor(new_scale); } else if (m_mode == Volume) { Eigen::Matrix new_matrix = (m * m_cache.volumes_data[i].get_volume_scale_matrix()).matrix().block(0, 0, 3, 3); @@ -894,11 +906,14 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); if (transformation_type.joint()) { Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() + m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center); - volume.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset); + v.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset); } - volume.set_volume_scaling_factor(new_scale); + v.set_volume_scaling_factor(new_scale); } } +#if ENABLE_SINKING_CONTOURS + v.update_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS } #if !DISABLE_INSTANCES_SYNCH @@ -972,6 +987,9 @@ void Selection::mirror(Axis axis) v.set_instance_mirror(axis, -(*m_volumes)[i]->get_instance_mirror(axis)); else if (m_mode == Volume) v.set_volume_mirror(axis, -(*m_volumes)[i]->get_volume_mirror(axis)); +#if ENABLE_SINKING_CONTOURS + v.update_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS } #if !DISABLE_INSTANCES_SYNCH From eb6392dccdba6486a4ff6c1858651a85f19dc264 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 26 Jul 2021 17:02:56 +0200 Subject: [PATCH 2/9] New slice_mesh() variant slicing with a single plane only, running on a single thread only (not parallelized). The new slice_mesh() is used to calculate contour of objects sunken below the print bed. --- src/libslic3r/TriangleMesh.cpp | 49 ++++++++------- src/libslic3r/TriangleMesh.hpp | 1 + src/libslic3r/TriangleMeshSlicer.cpp | 92 ++++++++++++++++++++++++++++ src/libslic3r/TriangleMeshSlicer.hpp | 6 ++ src/slic3r/GUI/3DScene.cpp | 10 ++- 5 files changed, 131 insertions(+), 27 deletions(-) diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index d709a67cd..360a8b14e 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -698,27 +698,29 @@ struct EdgeToFace { bool operator<(const EdgeToFace &other) const { return vertex_low < other.vertex_low || (vertex_low == other.vertex_low && vertex_high < other.vertex_high); } }; -template +template static std::vector create_edge_map( - const indexed_triangle_set &its, ThrowOnCancelCallback throw_on_cancel) + const indexed_triangle_set &its, FaceFilter face_filter, ThrowOnCancelCallback throw_on_cancel) { std::vector edges_map; - edges_map.assign(its.indices.size() * 3, EdgeToFace()); + edges_map.reserve(its.indices.size() * 3); for (uint32_t facet_idx = 0; facet_idx < its.indices.size(); ++ facet_idx) - for (int i = 0; i < 3; ++ i) { - EdgeToFace &e2f = edges_map[facet_idx * 3 + i]; - e2f.vertex_low = its.indices[facet_idx][i]; - e2f.vertex_high = its.indices[facet_idx][(i + 1) % 3]; - e2f.face = facet_idx; - // 1 based indexing, to be always strictly positive. - e2f.face_edge = i + 1; - if (e2f.vertex_low > e2f.vertex_high) { - // Sort the vertices - std::swap(e2f.vertex_low, e2f.vertex_high); - // and make the face_edge negative to indicate a flipped edge. - e2f.face_edge = - e2f.face_edge; + if (face_filter(facet_idx)) + for (int i = 0; i < 3; ++ i) { + edges_map.push_back({}); + EdgeToFace &e2f = edges_map.back(); + e2f.vertex_low = its.indices[facet_idx][i]; + e2f.vertex_high = its.indices[facet_idx][(i + 1) % 3]; + e2f.face = facet_idx; + // 1 based indexing, to be always strictly positive. + e2f.face_edge = i + 1; + if (e2f.vertex_low > e2f.vertex_high) { + // Sort the vertices + std::swap(e2f.vertex_low, e2f.vertex_high); + // and make the face_edge negative to indicate a flipped edge. + e2f.face_edge = - e2f.face_edge; + } } - } throw_on_cancel(); std::sort(edges_map.begin(), edges_map.end()); @@ -727,12 +729,12 @@ static std::vector create_edge_map( // Map from a face edge to a unique edge identifier or -1 if no neighbor exists. // Two neighbor faces share a unique edge identifier even if they are flipped. -template -static inline std::vector its_face_edge_ids_impl(const indexed_triangle_set &its, ThrowOnCancelCallback throw_on_cancel) +template +static inline std::vector its_face_edge_ids_impl(const indexed_triangle_set &its, FaceFilter face_filter, ThrowOnCancelCallback throw_on_cancel) { std::vector out(its.indices.size(), Vec3i(-1, -1, -1)); - std::vector edges_map = create_edge_map(its, throw_on_cancel); + std::vector edges_map = create_edge_map(its, face_filter, throw_on_cancel); // Assign a unique common edge id to touching triangle edges. int num_edges = 0; @@ -780,12 +782,17 @@ static inline std::vector its_face_edge_ids_impl(const indexed_triangle_s std::vector its_face_edge_ids(const indexed_triangle_set &its) { - return its_face_edge_ids_impl(its, [](){}); + return its_face_edge_ids_impl(its, [](const uint32_t){ return true; }, [](){}); } std::vector its_face_edge_ids(const indexed_triangle_set &its, std::function throw_on_cancel_callback) { - return its_face_edge_ids_impl(its, throw_on_cancel_callback); + return its_face_edge_ids_impl(its, [](const uint32_t){ return true; }, throw_on_cancel_callback); +} + +std::vector its_face_edge_ids(const indexed_triangle_set &its, const std::vector &face_mask) +{ + return its_face_edge_ids_impl(its, [&face_mask](const uint32_t idx){ return face_mask[idx]; }, [](){}); } // Having the face neighbors available, assign unique edge IDs to face edges for chaining of polygons over slices. diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 7aef3055a..c8c7e0dd7 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -118,6 +118,7 @@ private: // Used for chaining slice lines into polygons. std::vector its_face_edge_ids(const indexed_triangle_set &its); std::vector its_face_edge_ids(const indexed_triangle_set &its, std::function throw_on_cancel_callback); +std::vector its_face_edge_ids(const indexed_triangle_set &its, const std::vector &face_mask); // Having the face neighbors available, assign unique edge IDs to face edges for chaining of polygons over slices. std::vector its_face_edge_ids(const indexed_triangle_set &its, std::vector &face_neighbors, bool assign_unbound_edges = false, int *num_edges = nullptr); diff --git a/src/libslic3r/TriangleMeshSlicer.cpp b/src/libslic3r/TriangleMeshSlicer.cpp index 681ec32f0..ef90402a9 100644 --- a/src/libslic3r/TriangleMeshSlicer.cpp +++ b/src/libslic3r/TriangleMeshSlicer.cpp @@ -362,6 +362,35 @@ static inline std::vector slice_make_lines( return lines; } +template +static inline IntersectionLines slice_make_lines( + const std::vector &mesh_vertices, + const TransformVertex &transform_vertex_fn, + const std::vector &mesh_faces, + const std::vector &face_edge_ids, + const float plane_z, + FaceFilter face_filter) +{ + IntersectionLines lines; + for (int face_idx = 0; face_idx < mesh_faces.size(); ++ face_idx) + if (face_filter(face_idx)) { + const Vec3i &indices = mesh_faces[face_idx]; + stl_vertex vertices[3] { transform_vertex_fn(mesh_vertices[indices(0)]), transform_vertex_fn(mesh_vertices[indices(1)]), transform_vertex_fn(mesh_vertices[indices(2)]) }; + // find facet extents + const float min_z = fminf(vertices[0].z(), fminf(vertices[1].z(), vertices[2].z())); + const float max_z = fmaxf(vertices[0].z(), fmaxf(vertices[1].z(), vertices[2].z())); + assert(min_z <= plane_z && max_z >= plane_z); + int idx_vertex_lowest = (vertices[1].z() == min_z) ? 1 : ((vertices[2].z() == min_z) ? 2 : 0); + IntersectionLine il; + // Ignore horizontal triangles. Any valid horizontal triangle must have a vertical triangle connected, otherwise the part has zero volume. + if (min_z != max_z && slice_facet(plane_z, vertices, indices, face_edge_ids[face_idx], idx_vertex_lowest, false, il) == FacetSliceType::Slicing) { + assert(il.edge_type != IntersectionLine::FacetEdgeType::Horizontal); + lines.emplace_back(il); + } + } + return lines; +} + // For projecting triangle sets onto slice slabs. struct SlabLines { // Intersection lines of a slice with a triangle set, CCW oriented. @@ -1720,6 +1749,69 @@ std::vector slice_mesh( return layers; } +// Specialized version for a single slicing plane only, running on a single thread. +Polygons slice_mesh( + const indexed_triangle_set &mesh, + // Unscaled Zs + const float plane_z, + const MeshSlicingParams ¶ms) +{ + std::vector lines; + + { + bool trafo_identity = is_identity(params.trafo); + Transform3f tf; + std::vector face_mask(mesh.indices.size(), false); + + { + // 1) Mark vertices as below or above the slicing plane. + std::vector vertex_side(mesh.vertices.size(), 0); + if (trafo_identity) { + for (size_t i = 0; i < mesh.vertices.size(); ++ i) { + float z = mesh.vertices[i].z(); + char s = z < plane_z ? -1 : z == plane_z ? 0 : 1; + vertex_side[i] = s; + } + } else { + tf = make_trafo_for_slicing(params.trafo); + for (size_t i = 0; i < mesh.vertices.size(); ++ i) { + //FIXME don't need to transform x & y, just Z. + float z = (tf * mesh.vertices[i]).z(); + char s = z < plane_z ? -1 : z == plane_z ? 0 : 1; + vertex_side[i] = s; + } + } + + // 2) Mark faces crossing the plane. + for (size_t i = 0; i < mesh.indices.size(); ++ i) { + const Vec3i &face = mesh.indices[i]; + int sides[3] = { vertex_side[face(0)], vertex_side[face(1)], vertex_side[face(2)] }; + face_mask[i] = sides[0] * sides[1] <= 0 || sides[1] * sides[2] <= 0 || sides[0] * sides[2] <= 0; + } + } + + // 3) Calculate face neighbors for just the faces in face_mask. + std::vector face_edge_ids = its_face_edge_ids(mesh, face_mask); + + // 4) Slice "face_mask" triangles, collect line segments. + // It likely is not worthwile to copy the vertices. Apply the transformation in place. + if (trafo_identity) { + lines.emplace_back(slice_make_lines( + mesh.vertices, [](const Vec3f &p) { return Vec3f(scaled(p.x()), scaled(p.y()), p.z()); }, + mesh.indices, face_edge_ids, plane_z, [&face_mask](int face_idx) { return face_mask[face_idx]; })); + } else { + // Transform the vertices, scale up in XY, not in Z. + lines.emplace_back(slice_make_lines(mesh.vertices, [tf](const Vec3f& p) { return tf * p; }, mesh.indices, face_edge_ids, plane_z, + [&face_mask](int face_idx) { return face_mask[face_idx]; })); + } + } + + // 5) Chain the line segments. + std::vector layers = make_loops(lines, params, [](){}); + assert(layers.size() == 1); + return layers.front(); +} + std::vector slice_mesh_ex( const indexed_triangle_set &mesh, const std::vector &zs, diff --git a/src/libslic3r/TriangleMeshSlicer.hpp b/src/libslic3r/TriangleMeshSlicer.hpp index 9b02f5573..7ea7ac3a9 100644 --- a/src/libslic3r/TriangleMeshSlicer.hpp +++ b/src/libslic3r/TriangleMeshSlicer.hpp @@ -52,6 +52,12 @@ std::vector slice_mesh( const MeshSlicingParams ¶ms, std::function throw_on_cancel = []{}); +// Specialized version for a single slicing plane only, running on a single thread. +Polygons slice_mesh( + const indexed_triangle_set &mesh, + const float plane_z, + const MeshSlicingParams ¶ms); + std::vector slice_mesh_ex( const indexed_triangle_set &mesh, const std::vector &zs, diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index f2c2ee833..4e2c21cf6 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -302,7 +302,7 @@ void GLVolume::SinkingContours::update() #if ALG_SLICE == ALG_SLICE_MESH MeshSlicingParams slicing_params; slicing_params.trafo = m_parent.world_matrix(); - std::vector list_of_polys = slice_mesh(mesh.its, std::vector{ 0.0f }, slicing_params); + Polygons polygons = slice_mesh(mesh.its, 0.0f, slicing_params); auto append_polygon = [this](const Polygon& polygon, GUI::GLModel::InitializationData& data) { if (!polygon.empty()) { @@ -326,11 +326,9 @@ void GLVolume::SinkingContours::update() m_model.reset(); GUI::GLModel::InitializationData init_data; - for (const Polygons& polygons : list_of_polys) { - for (const Polygon& polygon : polygons) { - // contour - append_polygon(polygon, init_data); - } + for (const Polygon& polygon : polygons) { + // contour + append_polygon(polygon, init_data); } #else MeshSlicingParamsEx slicing_params; From b24488ce51f64a42c8180be174b5b1ac2b4c7958 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 27 Jul 2021 13:02:06 +0200 Subject: [PATCH 3/9] Tech ENABLE_SINKING_CONTOURS -> Sinking contours shown while dragging Move/Rotate/Scale gizmos and show contours for gizmo cut --- src/slic3r/GUI/3DScene.cpp | 87 ++++---------------- src/slic3r/GUI/3DScene.hpp | 6 +- src/slic3r/GUI/GLCanvas3D.cpp | 25 ++++++ src/slic3r/GUI/GLModel.cpp | 32 +++++++ src/slic3r/GUI/GLModel.hpp | 7 ++ src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 8 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 58 +++++++++++-- src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 30 +++++-- src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 8 +- src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoMove.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 12 +-- src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 10 +-- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoScale.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 4 +- 21 files changed, 200 insertions(+), 123 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 4e2c21cf6..c416bbabc 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -285,9 +285,6 @@ void GLIndexedVertexArray::render( } #if ENABLE_SINKING_CONTOURS -#define ALG_SLICE_MESH 1 -#define ALG_SLICE_MESHEX 2 -#define ALG_SLICE ALG_SLICE_MESH void GLVolume::SinkingContours::update() { if (m_parent.is_sinking() && !m_parent.is_below_printbed()) { @@ -299,78 +296,19 @@ void GLVolume::SinkingContours::update() const TriangleMesh& mesh = GUI::wxGetApp().plater()->model().objects[m_parent.object_idx()]->volumes[m_parent.volume_idx()]->mesh(); assert(mesh.has_shared_vertices()); -#if ALG_SLICE == ALG_SLICE_MESH MeshSlicingParams slicing_params; slicing_params.trafo = m_parent.world_matrix(); Polygons polygons = slice_mesh(mesh.its, 0.0f, slicing_params); - auto append_polygon = [this](const Polygon& polygon, GUI::GLModel::InitializationData& data) { - if (!polygon.empty()) { - GUI::GLModel::InitializationData::Entity entity; - entity.type = GUI::GLModel::PrimitiveType::LineLoop; - entity.color[0] = 1.0f - m_parent.render_color[0]; - entity.color[1] = 1.0f - m_parent.render_color[1]; - entity.color[2] = 1.0f - m_parent.render_color[2]; - entity.color[3] = m_parent.render_color[3]; - // contour - entity.positions.reserve(polygon.size() + 1); - entity.indices.reserve(polygon.size() + 1); - unsigned int id = 0; - for (const Point& p : polygon) { - entity.positions.emplace_back(unscale(p.x(), p.y(), 0.0).cast()); - entity.indices.emplace_back(id++); - } - data.entities.emplace_back(entity); - } - }; - m_model.reset(); - GUI::GLModel::InitializationData init_data; - for (const Polygon& polygon : polygons) { - // contour - append_polygon(polygon, init_data); - } -#else - MeshSlicingParamsEx slicing_params; - slicing_params.trafo = m_parent.world_matrix(); - std::vector list_of_expolys = slice_mesh_ex(mesh.its, std::vector{ 0.0f }, slicing_params); - - auto append_polygon = [this](const Polygon& polygon, GUI::GLModel::InitializationData& data) { - if (!polygon.empty()) { - GUI::GLModel::InitializationData::Entity entity; - entity.type = GUI::GLModel::PrimitiveType::LineLoop; - entity.color[0] = 1.0f - m_parent.render_color[0]; - entity.color[1] = 1.0f - m_parent.render_color[1]; - entity.color[2] = 1.0f - m_parent.render_color[2]; - entity.color[3] = m_parent.render_color[3]; - // contour - entity.positions.reserve(polygon.size() + 1); - entity.indices.reserve(polygon.size() + 1); - unsigned int id = 0; - for (const Point& p : polygon) { - entity.positions.emplace_back(unscale(p.x(), p.y(), 0.0).cast()); - entity.indices.emplace_back(id++); - } - data.entities.emplace_back(entity); - } + m_model.init_from(polygons, 0.0f); + std::array color = { + 1.0f - m_parent.render_color[0], + 1.0f - m_parent.render_color[1], + 1.0f - m_parent.render_color[2], + m_parent.render_color[3] }; - - m_model.reset(); - GUI::GLModel::InitializationData init_data; - for (const ExPolygons& polygons : list_of_expolys) { - for (const ExPolygon& polygon : polygons) { - // contour - append_polygon(polygon.contour, init_data); - // holes - for (const Polygon& hole : polygon.holes) { - append_polygon(hole, init_data); - } - } - } -#endif // ALG_SLICE == ALG_SLICE_MESH - - if (!init_data.entities.empty()) - m_model.init_from(init_data); + m_model.set_color(-1, color); } else m_shift = box.center() - m_old_box.center(); @@ -433,6 +371,9 @@ GLVolume::GLVolume(float r, float g, float b, float a) , force_transparent(false) , force_native_color(false) , force_neutral_color(false) +#if ENABLE_SINKING_CONTOURS + , force_sinking_contours(false) +#endif // ENABLE_SINKING_CONTOURS , tverts_range(0, size_t(-1)) , qverts_range(0, size_t(-1)) { @@ -887,7 +828,8 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab volume.first->set_render_color(); // render sinking contours of non-hovered volumes - if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover == GLVolume::HS_None) { + if (volume.first->is_sinking() && !volume.first->is_below_printbed() && + volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) { shader->stop_using(); glsafe(::glLineWidth(5.0f)); volume.first->update_sinking_contours_color(); @@ -933,8 +875,9 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab } for (GLVolumeWithIdAndZ& volume : to_render) { - // render sinking contours of hovered volumes - if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover != GLVolume::HS_None) { + // render sinking contours of hovered/displaced volumes + if (volume.first->is_sinking() && !volume.first->is_below_printbed() && + (volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) { shader->stop_using(); glsafe(::glLineWidth(5.0f)); glsafe(::glDisable(GL_DEPTH_TEST)); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 3431def90..f61df9294 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -359,7 +359,11 @@ public: bool force_native_color : 1; // Whether or not render this volume in neutral bool force_neutral_color : 1; - }; +#if ENABLE_SINKING_CONTOURS + // Whether or not to force rendering of sinking contours + bool force_sinking_contours : 1; +#endif // ENABLE_SINKING_CONTOURS + }; // Is mouse or rectangle selection over this object to select/deselect it ? EHoverState hover; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 91059d701..39213dc2c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2964,6 +2964,12 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) return; } +#if ENABLE_SINKING_CONTOURS + for (GLVolume* volume : m_volumes.volumes) { + volume->force_sinking_contours = false; + } +#endif // ENABLE_SINKING_CONTOURS + if (m_gizmos.on_mouse(evt)) { if (wxWindow::FindFocus() != m_canvas) // Grab keyboard focus for input in gizmo dialogs. @@ -2988,6 +2994,25 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) default: { break; } } } +#if ENABLE_SINKING_CONTOURS + else if (evt.Dragging()) { + switch (m_gizmos.get_current_type()) + { + case GLGizmosManager::EType::Move: + case GLGizmosManager::EType::Scale: + case GLGizmosManager::EType::Rotate: + { + const Selection::IndicesList& idxs = m_selection.get_volume_idxs(); + for (unsigned int idx : idxs) { + m_volumes.volumes[idx]->force_sinking_contours = true; + } + m_dirty = true; + break; + } + default: { break; } + } + } +#endif // ENABLE_SINKING_CONTOURS return; } diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 6cc09c7ba..0fb6668c6 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -7,6 +7,9 @@ #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Model.hpp" +#if ENABLE_SINKING_CONTOURS +#include "libslic3r/Polygon.hpp" +#endif // ENABLE_SINKING_CONTOURS #include #include @@ -87,6 +90,35 @@ void GLModel::init_from(const TriangleMesh& mesh) m_render_data.emplace_back(data); } +#if ENABLE_SINKING_CONTOURS +void GLModel::init_from(const Polygons& polygons, float z) +{ + auto append_polygon = [this](const Polygon& polygon, float z, GUI::GLModel::InitializationData& data) { + if (!polygon.empty()) { + GUI::GLModel::InitializationData::Entity entity; + entity.type = GUI::GLModel::PrimitiveType::LineLoop; + // contour + entity.positions.reserve(polygon.size() + 1); + entity.indices.reserve(polygon.size() + 1); + unsigned int id = 0; + for (const Point& p : polygon) { + Vec3f position = unscale(p.x(), p.y(), 0.0).cast(); + position.z() = z; + entity.positions.emplace_back(position); + entity.indices.emplace_back(id++); + } + data.entities.emplace_back(entity); + } + }; + + InitializationData init_data; + for (const Polygon& polygon : polygons) { + append_polygon(polygon, z, init_data); + } + init_from(init_data); +} +#endif // ENABLE_SINKING_CONTOURS + bool GLModel::init_from_file(const std::string& filename) { if (!boost::filesystem::exists(filename)) diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index ee3d2f8f9..cab2fe220 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -9,6 +9,10 @@ namespace Slic3r { class TriangleMesh; +#if ENABLE_SINKING_CONTOURS +class Polygon; +using Polygons = std::vector; +#endif // ENABLE_SINKING_CONTOURS namespace GUI { @@ -58,6 +62,9 @@ namespace GUI { void init_from(const InitializationData& data); void init_from(const TriangleMesh& mesh); +#if ENABLE_SINKING_CONTOURS + void init_from(const Polygons& polygons, float z); +#endif // ENABLE_SINKING_CONTOURS bool init_from_file(const std::string& filename); // if entity_id == -1 set the color of all entities diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index ac83b794b..2fb9c296a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -154,8 +154,8 @@ public: void update(const UpdateData& data); - void render() const { m_tooltip.clear(); on_render(); } - void render_for_picking() const { on_render_for_picking(); } + void render() { m_tooltip.clear(); on_render(); } + void render_for_picking() { on_render_for_picking(); } void render_input_window(float x, float y, float bottom_limit); virtual std::string get_tooltip() const { return ""; } @@ -175,8 +175,8 @@ protected: virtual void on_start_dragging() {} virtual void on_stop_dragging() {} virtual void on_update(const UpdateData& data) {} - virtual void on_render() const = 0; - virtual void on_render_for_picking() const = 0; + virtual void on_render() = 0; + virtual void on_render_for_picking() = 0; virtual void on_render_input_window(float x, float y, float bottom_limit) {} // Returns the picking color for the given id, based on the BASE_ID constant diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 6fc382cbc..d6ebc0dd3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -16,7 +16,9 @@ #include "slic3r/GUI/GUI_ObjectManipulation.hpp" #include "libslic3r/AppConfig.hpp" #include "libslic3r/Model.hpp" - +#if ENABLE_SINKING_CONTOURS +#include "libslic3r/TriangleMeshSlicer.hpp" +#endif // ENABLE_SINKING_CONTOURS namespace Slic3r { namespace GUI { @@ -82,9 +84,9 @@ void GLGizmoCut::on_update(const UpdateData& data) set_cut_z(m_start_z + calc_projection(data.mouse_ray)); } -void GLGizmoCut::on_render() const +void GLGizmoCut::on_render() { - BoundingBoxf3 box = bounding_box(); + const BoundingBoxf3 box = bounding_box(); Vec3d plane_center = box.center(); plane_center.z() = m_cut_z; m_max_z = box.max.z(); @@ -136,9 +138,16 @@ void GLGizmoCut::on_render() const m_grabbers[0].render(m_hover_id == 0, (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0)); shader->stop_using(); + +#if ENABLE_SINKING_CONTOURS + glsafe(::glPushMatrix()); + glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z())); + m_cut_contours.contours.render(); + glsafe(::glPopMatrix()); +#endif // ENABLE_SINKING_CONTOURS } -void GLGizmoCut::on_render_for_picking() const +void GLGizmoCut::on_render_for_picking() { glsafe(::glDisable(GL_DEPTH_TEST)); render_grabbers_for_picking(m_parent.get_selection().get_bounding_box()); @@ -199,10 +208,49 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit) perform_cut(m_parent.get_selection()); } -void GLGizmoCut::set_cut_z(double cut_z) const +void GLGizmoCut::set_cut_z(double cut_z) { // Clamp the plane to the object's bounding box m_cut_z = std::clamp(cut_z, 0.0, m_max_z); + +#if ENABLE_SINKING_CONTOURS + const Selection& selection = m_parent.get_selection(); + const GLVolume* first_glvolume = selection.get_volume(*selection.get_volume_idxs().begin()); + const BoundingBoxf3& box = first_glvolume->transformed_convex_hull_bounding_box(); + + const int object_idx = selection.get_object_idx(); + const int instance_idx = selection.get_instance_idx(); + + if (0.0 < m_cut_z && m_cut_z < m_max_z) { + if (m_cut_contours.cut_z != m_cut_z || m_cut_contours.object_idx != object_idx || m_cut_contours.instance_idx != instance_idx) { + m_cut_contours.cut_z = m_cut_z; + + if (m_cut_contours.object_idx != object_idx) { + m_cut_contours.mesh = wxGetApp().plater()->model().objects[object_idx]->raw_mesh(); + m_cut_contours.mesh.repair(); + } + + m_cut_contours.position = box.center(); + m_cut_contours.shift = Vec3d::Zero(); + m_cut_contours.object_idx = object_idx; + m_cut_contours.instance_idx = instance_idx; + m_cut_contours.contours.reset(); + + MeshSlicingParams slicing_params; + slicing_params.trafo = first_glvolume->get_instance_transformation().get_matrix(); + const Polygons polys = slice_mesh(m_cut_contours.mesh.its, m_cut_z, slicing_params); + if (!polys.empty()) { + m_cut_contours.contours.init_from(polys, static_cast(m_cut_z)); + m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f }); + } + } + else if (box.center() != m_cut_contours.position) { + m_cut_contours.shift = box.center() - m_cut_contours.position; + } + } + else + m_cut_contours.contours.reset(); +#endif // ENABLE_SINKING_CONTOURS } void GLGizmoCut::perform_cut(const Selection& selection) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index dd80c4d69..ea9972519 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -2,7 +2,10 @@ #define slic3r_GLGizmoCut_hpp_ #include "GLGizmoBase.hpp" - +#if ENABLE_SINKING_CONTOURS +#include "slic3r/GUI/GLModel.hpp" +#include "libslic3r/TriangleMesh.hpp" +#endif // ENABLE_SINKING_CONTOURS namespace Slic3r { namespace GUI { @@ -13,8 +16,8 @@ class GLGizmoCut : public GLGizmoBase static const double Margin; static const std::array GrabberColor; - mutable double m_cut_z{ 0.0 }; - mutable double m_max_z{ 0.0 }; + double m_cut_z{ 0.0 }; + double m_max_z{ 0.0 }; double m_start_z{ 0.0 }; Vec3d m_drag_pos; Vec3d m_drag_center; @@ -22,11 +25,26 @@ class GLGizmoCut : public GLGizmoBase bool m_keep_lower{ true }; bool m_rotate_lower{ false }; +#if ENABLE_SINKING_CONTOURS + struct CutContours + { + TriangleMesh mesh; + GLModel contours; + double cut_z{ 0.0 }; + Vec3d position{ Vec3d::Zero() }; + Vec3d shift{ Vec3d::Zero() }; + int object_idx{ -1 }; + int instance_idx{ -1 }; + }; + + CutContours m_cut_contours; +#endif // ENABLE_SINKING_CONTOURS + public: GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); double get_cut_z() const { return m_cut_z; } - void set_cut_z(double cut_z) const; + void set_cut_z(double cut_z); std::string get_tooltip() const override; @@ -39,8 +57,8 @@ protected: virtual bool on_is_activable() const override; virtual void on_start_dragging() override; virtual void on_update(const UpdateData& data) override; - virtual void on_render() const override; - virtual void on_render_for_picking() const override; + virtual void on_render() override; + virtual void on_render_for_picking() override; virtual void on_render_input_window(float x, float y, float bottom_limit) override; private: diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index fc5edff6d..094805abc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -54,7 +54,7 @@ void GLGizmoFlatten::on_start_dragging() } } -void GLGizmoFlatten::on_render() const +void GLGizmoFlatten::on_render() { const Selection& selection = m_parent.get_selection(); @@ -69,7 +69,7 @@ void GLGizmoFlatten::on_render() const glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z())); glsafe(::glMultMatrixd(m.data())); if (this->is_plane_update_necessary()) - const_cast(this)->update_planes(); + update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { if (i == m_hover_id) glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.75f)); @@ -86,7 +86,7 @@ void GLGizmoFlatten::on_render() const glsafe(::glDisable(GL_BLEND)); } -void GLGizmoFlatten::on_render_for_picking() const +void GLGizmoFlatten::on_render_for_picking() { const Selection& selection = m_parent.get_selection(); @@ -99,7 +99,7 @@ void GLGizmoFlatten::on_render_for_picking() const glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z())); glsafe(::glMultMatrixd(m.data())); if (this->is_plane_update_necessary()) - const_cast(this)->update_planes(); + update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { glsafe(::glColor4fv(picking_color_component(i).data())); m_planes[i].vbo.render(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp index f6fe06451..ab3c2c7ba 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp @@ -53,8 +53,8 @@ protected: virtual std::string on_get_name() const override; virtual bool on_is_activable() const override; virtual void on_start_dragging() override; - virtual void on_render() const override; - virtual void on_render_for_picking() const override; + virtual void on_render() override; + virtual void on_render_for_picking() override; virtual void on_set_state() override; virtual CommonGizmosDataID on_get_requirements() const override; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 9d2de1d03..46608b4c7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -61,7 +61,7 @@ void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&) -void GLGizmoHollow::on_render() const +void GLGizmoHollow::on_render() { const Selection& selection = m_parent.get_selection(); const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info(); @@ -88,7 +88,7 @@ void GLGizmoHollow::on_render() const } -void GLGizmoHollow::on_render_for_picking() const +void GLGizmoHollow::on_render_for_picking() { const Selection& selection = m_parent.get_selection(); //#if ENABLE_RENDER_PICKING_PASS diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index 1bcf1713e..2cf08de2a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -39,8 +39,8 @@ public: private: bool on_init() override; void on_update(const UpdateData& data) override; - void on_render() const override; - void on_render_for_picking() const override; + void on_render() override; + void on_render_for_picking() override; void render_points(const Selection& selection, bool picking = false) const; void hollow_mesh(bool postpone_error_messages = false); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 7a9e69fac..1211864eb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -87,7 +87,7 @@ void GLGizmoMove3D::on_update(const UpdateData& data) m_displacement.z() = calc_projection(data); } -void GLGizmoMove3D::on_render() const +void GLGizmoMove3D::on_render() { const Selection& selection = m_parent.get_selection(); @@ -151,7 +151,7 @@ void GLGizmoMove3D::on_render() const } } -void GLGizmoMove3D::on_render_for_picking() const +void GLGizmoMove3D::on_render_for_picking() { glsafe(::glDisable(GL_DEPTH_TEST)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index 9a86852d6..baa2df739 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -39,8 +39,8 @@ protected: virtual void on_start_dragging() override; virtual void on_stop_dragging() override; virtual void on_update(const UpdateData& data) override; - virtual void on_render() const override; - virtual void on_render_for_picking() const override; + virtual void on_render() override; + virtual void on_render_for_picking() override; private: double calc_projection(const UpdateData& data) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index a551759b6..04c74c487 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -66,8 +66,8 @@ class GLGizmoPainterBase : public GLGizmoBase private: ObjectID m_old_mo_id; size_t m_old_volumes_size = 0; - void on_render() const override {} - void on_render_for_picking() const override {} + void on_render() override {} + void on_render_for_picking() override {} public: GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 8b12bdc3d..a495db4f1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -125,7 +125,7 @@ void GLGizmoRotate::on_update(const UpdateData& data) m_angle = theta; } -void GLGizmoRotate::on_render() const +void GLGizmoRotate::on_render() { if (!m_grabbers[0].enabled) return; @@ -169,7 +169,7 @@ void GLGizmoRotate::on_render() const glsafe(::glPopMatrix()); } -void GLGizmoRotate::on_render_for_picking() const +void GLGizmoRotate::on_render_for_picking() { const Selection& selection = m_parent.get_selection(); @@ -483,17 +483,17 @@ void GLGizmoRotate3D::on_stop_dragging() m_gizmos[m_hover_id].stop_dragging(); } -void GLGizmoRotate3D::on_render() const +void GLGizmoRotate3D::on_render() { glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); - if ((m_hover_id == -1) || (m_hover_id == 0)) + if (m_hover_id == -1 || m_hover_id == 0) m_gizmos[X].render(); - if ((m_hover_id == -1) || (m_hover_id == 1)) + if (m_hover_id == -1 || m_hover_id == 1) m_gizmos[Y].render(); - if ((m_hover_id == -1) || (m_hover_id == 2)) + if (m_hover_id == -1 || m_hover_id == 2) m_gizmos[Z].render(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index 3fc347222..a51f900bf 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -55,8 +55,8 @@ protected: std::string on_get_name() const override { return ""; } void on_start_dragging() override; void on_update(const UpdateData& data) override; - void on_render() const override; - void on_render_for_picking() const override; + void on_render() override; + void on_render_for_picking() override; private: void render_circle() const; @@ -124,10 +124,10 @@ protected: g.update(data); } } - void on_render() const override; - void on_render_for_picking() const override + void on_render() override; + void on_render_for_picking() override { - for (const GLGizmoRotate& g : m_gizmos) { + for (GLGizmoRotate& g : m_gizmos) { g.render_for_picking(); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index fb1b148b4..849046962 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -115,7 +115,7 @@ void GLGizmoScale3D::on_update(const UpdateData& data) do_scale_uniform(data); } -void GLGizmoScale3D::on_render() const +void GLGizmoScale3D::on_render() { const Selection& selection = m_parent.get_selection(); @@ -294,7 +294,7 @@ void GLGizmoScale3D::on_render() const } } -void GLGizmoScale3D::on_render_for_picking() const +void GLGizmoScale3D::on_render_for_picking() { glsafe(::glDisable(GL_DEPTH_TEST)); render_grabbers_for_picking(m_parent.get_selection().get_bounding_box()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp index 39021640a..35615df4a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp @@ -52,8 +52,8 @@ protected: virtual bool on_is_activable() const override; virtual void on_start_dragging() override; virtual void on_update(const UpdateData& data) override; - virtual void on_render() const override; - virtual void on_render_for_picking() const override; + virtual void on_render() override; + virtual void on_render_for_picking() override; private: void render_grabbers_connection(unsigned int id_1, unsigned int id_2) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index f28f060bd..39107e7be 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -74,7 +74,7 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S -void GLGizmoSlaSupports::on_render() const +void GLGizmoSlaSupports::on_render() { ModelObject* mo = m_c->selection_info()->model_object(); const Selection& selection = m_parent.get_selection(); @@ -101,7 +101,7 @@ void GLGizmoSlaSupports::on_render() const } -void GLGizmoSlaSupports::on_render_for_picking() const +void GLGizmoSlaSupports::on_render_for_picking() { const Selection& selection = m_parent.get_selection(); //glsafe(::glEnable(GL_DEPTH_TEST)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 1859dbfd1..6982ecf76 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -70,8 +70,8 @@ public: private: bool on_init() override; void on_update(const UpdateData& data) override; - void on_render() const override; - void on_render_for_picking() const override; + void on_render() override; + void on_render_for_picking() override; void render_points(const Selection& selection, bool picking = false) const; bool unsaved_changes() const; From d99ea7c20f0269f3dc5def996d127aceec687a4b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 28 Jul 2021 11:21:59 +0200 Subject: [PATCH 4/9] Tech ENABLE_SINKING_CONTOURS -> Sinking contours rendered using triangles --- src/slic3r/GUI/3DScene.cpp | 48 +++++++++++++++++++++------- src/slic3r/GUI/3DScene.hpp | 1 + src/slic3r/GUI/GLCanvas3D.cpp | 8 ++--- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 1 + 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index c416bbabc..63fe333d7 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -24,6 +24,9 @@ #include "libslic3r/Utils.hpp" #include "libslic3r/AppConfig.hpp" #include "libslic3r/PresetBundle.hpp" +#if ENABLE_SINKING_CONTOURS +#include "libslic3r/Tesselate.hpp" +#endif // ENABLE_SINKING_CONTOURS #include #include @@ -285,6 +288,8 @@ void GLIndexedVertexArray::render( } #if ENABLE_SINKING_CONTOURS +const float GLVolume::SinkingContours::HalfWidth = 0.25f; + void GLVolume::SinkingContours::update() { if (m_parent.is_sinking() && !m_parent.is_below_printbed()) { @@ -301,14 +306,35 @@ void GLVolume::SinkingContours::update() Polygons polygons = slice_mesh(mesh.its, 0.0f, slicing_params); m_model.reset(); - m_model.init_from(polygons, 0.0f); - std::array color = { - 1.0f - m_parent.render_color[0], - 1.0f - m_parent.render_color[1], - 1.0f - m_parent.render_color[2], - m_parent.render_color[3] - }; - m_model.set_color(-1, color); + GUI::GLModel::InitializationData init_data; + for (const Polygon& polygon : polygons) { + const Polygons outer_polys = offset(polygon, float(scale_(HalfWidth))); + const Polygons inner_polys = offset(polygon, -float(scale_(HalfWidth))); + + if (outer_polys.empty()) + // no outer contour, skip + continue; + + const ExPolygons diff_polys_ex = diff_ex(outer_polys, inner_polys); + + for (const ExPolygon& poly : diff_polys_ex) { + GUI::GLModel::InitializationData::Entity entity; + entity.type = GUI::GLModel::PrimitiveType::Triangles; + const std::vector triangulation = triangulate_expolygon_3d(poly); + for (const Vec3d& v : triangulation) { + entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.015f)); // add a small positive z to avoid z-fighting + entity.normals.emplace_back(Vec3f::UnitZ()); + const size_t positions_count = entity.positions.size(); + if (positions_count % 3 == 0) { + entity.indices.emplace_back(positions_count - 3); + entity.indices.emplace_back(positions_count - 2); + entity.indices.emplace_back(positions_count - 1); + } + } + init_data.entities.emplace_back(entity); + } + } + m_model.init_from(init_data); } else m_shift = box.center() - m_old_box.center(); @@ -831,7 +857,6 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) { shader->stop_using(); - glsafe(::glLineWidth(5.0f)); volume.first->update_sinking_contours_color(); volume.first->render_sinking_contours(); shader->start_using(); @@ -879,11 +904,10 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab if (volume.first->is_sinking() && !volume.first->is_below_printbed() && (volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) { shader->stop_using(); - glsafe(::glLineWidth(5.0f)); - glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDepthFunc(GL_ALWAYS)); volume.first->update_sinking_contours_color(); volume.first->render_sinking_contours(); - glsafe(::glEnable(GL_DEPTH_TEST)); + glsafe(::glDepthFunc(GL_LESS)); shader->start_using(); } } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index f61df9294..1e1668dcd 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -284,6 +284,7 @@ private: #if ENABLE_SINKING_CONTOURS class SinkingContours { + static const float HalfWidth; GLVolume& m_parent; GUI::GLModel m_model; BoundingBoxf3 m_old_box; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 39213dc2c..87b487e6a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -792,7 +792,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons for (const Polygon& poly : polygons) { triangles_count += poly.points.size() - 2; } - size_t vertices_count = 3 * triangles_count; + const size_t vertices_count = 3 * triangles_count; if (m_render_fill) { GLModel::InitializationData fill_data; @@ -803,13 +803,13 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons entity.normals.reserve(vertices_count); entity.indices.reserve(vertices_count); - ExPolygons polygons_union = union_ex(polygons); + const ExPolygons polygons_union = union_ex(polygons); for (const ExPolygon& poly : polygons_union) { - std::vector triangulation = triangulate_expolygon_3d(poly, false); + const std::vector triangulation = triangulate_expolygon_3d(poly); for (const Vec3d& v : triangulation) { entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.0125f)); // add a small positive z to avoid z-fighting entity.normals.emplace_back(Vec3f::UnitZ()); - size_t positions_count = entity.positions.size(); + const size_t positions_count = entity.positions.size(); if (positions_count % 3 == 0) { entity.indices.emplace_back(positions_count - 3); entity.indices.emplace_back(positions_count - 2); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index d6ebc0dd3..30e40b5e5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -142,6 +142,7 @@ void GLGizmoCut::on_render() #if ENABLE_SINKING_CONTOURS glsafe(::glPushMatrix()); glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z())); + glsafe(::glLineWidth(2.0f)); m_cut_contours.contours.render(); glsafe(::glPopMatrix()); #endif // ENABLE_SINKING_CONTOURS From 0146013b4e8acfb114c2f7ce5f4d0842a31e77d9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 28 Jul 2021 12:23:27 +0200 Subject: [PATCH 5/9] Tech ENABLE_SINKING_CONTOURS -> Sinking contours updated during render pass and shown also while dragging an object --- src/slic3r/GUI/3DScene.cpp | 18 +++++------------- src/slic3r/GUI/3DScene.hpp | 4 +--- src/slic3r/GUI/GLCanvas3D.cpp | 23 ++++++++++++----------- src/slic3r/GUI/Selection.cpp | 18 ------------------ 4 files changed, 18 insertions(+), 45 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 63fe333d7..9213d656e 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -335,6 +335,7 @@ void GLVolume::SinkingContours::update() } } m_model.init_from(init_data); + set_color(m_parent.render_color); } else m_shift = box.center() - m_old_box.center(); @@ -348,8 +349,10 @@ void GLVolume::SinkingContours::set_color(const std::array& color) m_model.set_color(-1, { 1.0f - color[0], 1.0f - color[1], 1.0f - color[2], color[3] }); } -void GLVolume::SinkingContours::render() const +void GLVolume::SinkingContours::render() { + update(); + glsafe(::glPushMatrix()); glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z())); m_model.render(); @@ -597,18 +600,9 @@ bool GLVolume::is_below_printbed() const } #if ENABLE_SINKING_CONTOURS -void GLVolume::update_sinking_contours() -{ - m_sinking_contours.update(); -} - -void GLVolume::update_sinking_contours_color() -{ - m_sinking_contours.set_color(render_color); -} - void GLVolume::render_sinking_contours() { + m_sinking_contours.set_color(render_color); m_sinking_contours.render(); } #endif // ENABLE_SINKING_CONTOURS @@ -857,7 +851,6 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) { shader->stop_using(); - volume.first->update_sinking_contours_color(); volume.first->render_sinking_contours(); shader->start_using(); } @@ -905,7 +898,6 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab (volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) { shader->stop_using(); glsafe(::glDepthFunc(GL_ALWAYS)); - volume.first->update_sinking_contours_color(); volume.first->render_sinking_contours(); glsafe(::glDepthFunc(GL_LESS)); shader->start_using(); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 1e1668dcd..a07ede85e 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -294,7 +294,7 @@ private: SinkingContours(GLVolume& volume) : m_parent(volume) {} void update(); void set_color(const std::array& color); - void render() const; + void render(); }; SinkingContours m_sinking_contours; @@ -492,8 +492,6 @@ public: bool is_sinking() const; bool is_below_printbed() const; #if ENABLE_SINKING_CONTOURS - void update_sinking_contours(); - void update_sinking_contours_color(); void render_sinking_contours(); #endif // ENABLE_SINKING_CONTOURS diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 87b487e6a..d76501e54 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2054,12 +2054,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re m_gizmos.update_data(); m_gizmos.refresh_on_off_state(); -#if ENABLE_SINKING_CONTOURS - for (GLVolume* v : m_volumes.volumes) { - v->update_sinking_contours(); - } -#endif // ENABLE_SINKING_CONTOURS - // Update the toolbar if (update_object_list) post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); @@ -2968,6 +2962,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) for (GLVolume* volume : m_volumes.volumes) { volume->force_sinking_contours = false; } + + auto show_sinking_contours = [this]() { + const Selection::IndicesList& idxs = m_selection.get_volume_idxs(); + for (unsigned int idx : idxs) { + m_volumes.volumes[idx]->force_sinking_contours = true; + } + m_dirty = true; + }; #endif // ENABLE_SINKING_CONTOURS if (m_gizmos.on_mouse(evt)) { @@ -3002,11 +3004,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) case GLGizmosManager::EType::Scale: case GLGizmosManager::EType::Rotate: { - const Selection::IndicesList& idxs = m_selection.get_volume_idxs(); - for (unsigned int idx : idxs) { - m_volumes.volumes[idx]->force_sinking_contours = true; - } - m_dirty = true; + show_sinking_contours(); break; } default: { break; } @@ -3137,6 +3135,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_selection.start_dragging(); m_mouse.drag.start_position_3D = m_mouse.scene_position; m_sequential_print_clearance_first_displacement = true; +#if ENABLE_SINKING_CONTOURS + show_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS m_moving = true; } } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index c44509256..e8d7cc621 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -674,9 +674,6 @@ void Selection::translate(const Vec3d& displacement, bool local) translation_type = Volume; } } -#if ENABLE_SINKING_CONTOURS - v.update_sinking_contours(); -#endif // ENABLE_SINKING_CONTOURS } #if !DISABLE_INSTANCES_SYNCH @@ -711,9 +708,6 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation()); v.set_volume_offset(m_cache.volumes_data[i].get_volume_position()); } -#if ENABLE_SINKING_CONTOURS - v.update_sinking_contours(); -#endif // ENABLE_SINKING_CONTOURS } } else { // this is not the wipe tower @@ -781,9 +775,6 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ v.set_volume_rotation(new_rotation); } } -#if ENABLE_SINKING_CONTOURS - v.update_sinking_contours(); -#endif // ENABLE_SINKING_CONTOURS } } @@ -828,9 +819,6 @@ void Selection::flattening_rotate(const Vec3d& normal) // Additional rotation to align tnormal with the down vector in the world coordinate space. auto extra_rotation = Eigen::Quaterniond().setFromTwoVectors(tnormal, - Vec3d::UnitZ()); v.set_instance_rotation(Geometry::extract_euler_angles(extra_rotation.toRotationMatrix() * m_cache.volumes_data[i].get_instance_rotation_matrix())); -#if ENABLE_SINKING_CONTOURS - v.update_sinking_contours(); -#endif // ENABLE_SINKING_CONTOURS } #if !DISABLE_INSTANCES_SYNCH @@ -901,9 +889,6 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type v.set_volume_scaling_factor(new_scale); } } -#if ENABLE_SINKING_CONTOURS - v.update_sinking_contours(); -#endif // ENABLE_SINKING_CONTOURS } #if !DISABLE_INSTANCES_SYNCH @@ -975,9 +960,6 @@ void Selection::mirror(Axis axis) v.set_instance_mirror(axis, -(*m_volumes)[i]->get_instance_mirror(axis)); else if (m_mode == Volume) v.set_volume_mirror(axis, -(*m_volumes)[i]->get_volume_mirror(axis)); -#if ENABLE_SINKING_CONTOURS - v.update_sinking_contours(); -#endif // ENABLE_SINKING_CONTOURS } #if !DISABLE_INSTANCES_SYNCH From f1cd3e22c432b7008c3e857738dccf4076fb20cf Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 28 Jul 2021 13:03:48 +0200 Subject: [PATCH 6/9] Tech ENABLE_SINKING_CONTOURS -> Cut gizmo: contours updated during render pass --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 85 +++++++++++++++------------- src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 3 + 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 30e40b5e5..707726e08 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -92,6 +92,10 @@ void GLGizmoCut::on_render() m_max_z = box.max.z(); set_cut_z(m_cut_z); +#if ENABLE_SINKING_CONTOURS + update_contours(); +#endif // ENABLE_SINKING_CONTOURS + const float min_x = box.min.x() - Margin; const float max_x = box.max.x() + Margin; const float min_y = box.min.y() - Margin; @@ -213,45 +217,6 @@ void GLGizmoCut::set_cut_z(double cut_z) { // Clamp the plane to the object's bounding box m_cut_z = std::clamp(cut_z, 0.0, m_max_z); - -#if ENABLE_SINKING_CONTOURS - const Selection& selection = m_parent.get_selection(); - const GLVolume* first_glvolume = selection.get_volume(*selection.get_volume_idxs().begin()); - const BoundingBoxf3& box = first_glvolume->transformed_convex_hull_bounding_box(); - - const int object_idx = selection.get_object_idx(); - const int instance_idx = selection.get_instance_idx(); - - if (0.0 < m_cut_z && m_cut_z < m_max_z) { - if (m_cut_contours.cut_z != m_cut_z || m_cut_contours.object_idx != object_idx || m_cut_contours.instance_idx != instance_idx) { - m_cut_contours.cut_z = m_cut_z; - - if (m_cut_contours.object_idx != object_idx) { - m_cut_contours.mesh = wxGetApp().plater()->model().objects[object_idx]->raw_mesh(); - m_cut_contours.mesh.repair(); - } - - m_cut_contours.position = box.center(); - m_cut_contours.shift = Vec3d::Zero(); - m_cut_contours.object_idx = object_idx; - m_cut_contours.instance_idx = instance_idx; - m_cut_contours.contours.reset(); - - MeshSlicingParams slicing_params; - slicing_params.trafo = first_glvolume->get_instance_transformation().get_matrix(); - const Polygons polys = slice_mesh(m_cut_contours.mesh.its, m_cut_z, slicing_params); - if (!polys.empty()) { - m_cut_contours.contours.init_from(polys, static_cast(m_cut_z)); - m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f }); - } - } - else if (box.center() != m_cut_contours.position) { - m_cut_contours.shift = box.center() - m_cut_contours.position; - } - } - else - m_cut_contours.contours.reset(); -#endif // ENABLE_SINKING_CONTOURS } void GLGizmoCut::perform_cut(const Selection& selection) @@ -310,5 +275,47 @@ BoundingBoxf3 GLGizmoCut::bounding_box() const return ret; } +#if ENABLE_SINKING_CONTOURS +void GLGizmoCut::update_contours() +{ + const Selection& selection = m_parent.get_selection(); + const GLVolume* first_glvolume = selection.get_volume(*selection.get_volume_idxs().begin()); + const BoundingBoxf3& box = first_glvolume->transformed_convex_hull_bounding_box(); + + const int object_idx = selection.get_object_idx(); + const int instance_idx = selection.get_instance_idx(); + + if (0.0 < m_cut_z && m_cut_z < m_max_z) { + if (m_cut_contours.cut_z != m_cut_z || m_cut_contours.object_idx != object_idx || m_cut_contours.instance_idx != instance_idx) { + m_cut_contours.cut_z = m_cut_z; + + if (m_cut_contours.object_idx != object_idx) { + m_cut_contours.mesh = wxGetApp().plater()->model().objects[object_idx]->raw_mesh(); + m_cut_contours.mesh.repair(); + } + + m_cut_contours.position = box.center(); + m_cut_contours.shift = Vec3d::Zero(); + m_cut_contours.object_idx = object_idx; + m_cut_contours.instance_idx = instance_idx; + m_cut_contours.contours.reset(); + + MeshSlicingParams slicing_params; + slicing_params.trafo = first_glvolume->get_instance_transformation().get_matrix(); + const Polygons polys = slice_mesh(m_cut_contours.mesh.its, m_cut_z, slicing_params); + if (!polys.empty()) { + m_cut_contours.contours.init_from(polys, static_cast(m_cut_z)); + m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f }); + } + } + else if (box.center() != m_cut_contours.position) { + m_cut_contours.shift = box.center() - m_cut_contours.position; + } + } + else + m_cut_contours.contours.reset(); +} +#endif // ENABLE_SINKING_CONTOURS + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index ea9972519..abd879350 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -65,6 +65,9 @@ private: void perform_cut(const Selection& selection); double calc_projection(const Linef3& mouse_ray) const; BoundingBoxf3 bounding_box() const; +#if ENABLE_SINKING_CONTOURS + void update_contours(); +#endif // ENABLE_SINKING_CONTOURS }; } // namespace GUI From d821fcba2dc2b7f79f373e29a1e696ad4f848b03 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 28 Jul 2021 14:27:57 +0200 Subject: [PATCH 7/9] Tech ENABLE_SINKING_CONTOURS -> Improved generation of sinking contours and color set to white --- src/slic3r/GUI/3DScene.cpp | 74 ++++++++++++++++++-------------------- src/slic3r/GUI/3DScene.hpp | 5 +-- 2 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 9213d656e..5894a750e 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -290,6 +290,16 @@ void GLIndexedVertexArray::render( #if ENABLE_SINKING_CONTOURS const float GLVolume::SinkingContours::HalfWidth = 0.25f; +void GLVolume::SinkingContours::render() +{ + update(); + + glsafe(::glPushMatrix()); + glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z())); + m_model.render(); + glsafe(::glPopMatrix()); +} + void GLVolume::SinkingContours::update() { if (m_parent.is_sinking() && !m_parent.is_below_printbed()) { @@ -301,41 +311,41 @@ void GLVolume::SinkingContours::update() const TriangleMesh& mesh = GUI::wxGetApp().plater()->model().objects[m_parent.object_idx()]->volumes[m_parent.volume_idx()]->mesh(); assert(mesh.has_shared_vertices()); - MeshSlicingParams slicing_params; - slicing_params.trafo = m_parent.world_matrix(); - Polygons polygons = slice_mesh(mesh.its, 0.0f, slicing_params); - m_model.reset(); GUI::GLModel::InitializationData init_data; - for (const Polygon& polygon : polygons) { - const Polygons outer_polys = offset(polygon, float(scale_(HalfWidth))); - const Polygons inner_polys = offset(polygon, -float(scale_(HalfWidth))); - + MeshSlicingParams slicing_params; + slicing_params.trafo = m_parent.world_matrix(); + Polygons polygons = union_(slice_mesh(mesh.its, 0.0f, slicing_params)); + for (Polygon& polygon : polygons) { + if (polygon.is_clockwise()) + polygon.reverse(); + Polygons outer_polys = offset(polygon, float(scale_(HalfWidth))); + assert(outer_polys.size() == 1); if (outer_polys.empty()) // no outer contour, skip continue; - const ExPolygons diff_polys_ex = diff_ex(outer_polys, inner_polys); + ExPolygon expoly(std::move(outer_polys.front())); + expoly.holes = offset(polygon, -float(scale_(HalfWidth))); + polygons_reverse(expoly.holes); - for (const ExPolygon& poly : diff_polys_ex) { - GUI::GLModel::InitializationData::Entity entity; - entity.type = GUI::GLModel::PrimitiveType::Triangles; - const std::vector triangulation = triangulate_expolygon_3d(poly); - for (const Vec3d& v : triangulation) { - entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.015f)); // add a small positive z to avoid z-fighting - entity.normals.emplace_back(Vec3f::UnitZ()); - const size_t positions_count = entity.positions.size(); - if (positions_count % 3 == 0) { - entity.indices.emplace_back(positions_count - 3); - entity.indices.emplace_back(positions_count - 2); - entity.indices.emplace_back(positions_count - 1); - } + GUI::GLModel::InitializationData::Entity entity; + entity.type = GUI::GLModel::PrimitiveType::Triangles; + const std::vector triangulation = triangulate_expolygon_3d(expoly); + for (const Vec3d& v : triangulation) { + entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.015f)); // add a small positive z to avoid z-fighting + entity.normals.emplace_back(Vec3f::UnitZ()); + const size_t positions_count = entity.positions.size(); + if (positions_count % 3 == 0) { + entity.indices.emplace_back(positions_count - 3); + entity.indices.emplace_back(positions_count - 2); + entity.indices.emplace_back(positions_count - 1); } - init_data.entities.emplace_back(entity); } + init_data.entities.emplace_back(entity); } + m_model.init_from(init_data); - set_color(m_parent.render_color); } else m_shift = box.center() - m_old_box.center(); @@ -343,21 +353,6 @@ void GLVolume::SinkingContours::update() else m_model.reset(); } - -void GLVolume::SinkingContours::set_color(const std::array& color) -{ - m_model.set_color(-1, { 1.0f - color[0], 1.0f - color[1], 1.0f - color[2], color[3] }); -} - -void GLVolume::SinkingContours::render() -{ - update(); - - glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z())); - m_model.render(); - glsafe(::glPopMatrix()); -} #endif // ENABLE_SINKING_CONTOURS const std::array GLVolume::SELECTED_COLOR = { 0.0f, 1.0f, 0.0f, 1.0f }; @@ -602,7 +597,6 @@ bool GLVolume::is_below_printbed() const #if ENABLE_SINKING_CONTOURS void GLVolume::render_sinking_contours() { - m_sinking_contours.set_color(render_color); m_sinking_contours.render(); } #endif // ENABLE_SINKING_CONTOURS diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index a07ede85e..a257db56a 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -292,9 +292,10 @@ private: public: SinkingContours(GLVolume& volume) : m_parent(volume) {} - void update(); - void set_color(const std::array& color); void render(); + + private: + void update(); }; SinkingContours m_sinking_contours; From 1ea541767f50b6d6671775f1130ca66646154e11 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 28 Jul 2021 15:40:55 +0200 Subject: [PATCH 8/9] Fixed compile warning --- src/slic3r/GUI/GLModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 0fb6668c6..6d54ec20e 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -93,7 +93,7 @@ void GLModel::init_from(const TriangleMesh& mesh) #if ENABLE_SINKING_CONTOURS void GLModel::init_from(const Polygons& polygons, float z) { - auto append_polygon = [this](const Polygon& polygon, float z, GUI::GLModel::InitializationData& data) { + auto append_polygon = [](const Polygon& polygon, float z, GUI::GLModel::InitializationData& data) { if (!polygon.empty()) { GUI::GLModel::InitializationData::Entity entity; entity.type = GUI::GLModel::PrimitiveType::LineLoop; From 97de72314699aba8e53e3d3fb32a949c79c49751 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 29 Jul 2021 09:03:20 +0200 Subject: [PATCH 9/9] Tech ENABLE_SINKING_CONTOURS -> Fix for showing sinking contours while dragging objects --- src/slic3r/GUI/GLCanvas3D.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d76501e54..6a40a4e44 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3135,9 +3135,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_selection.start_dragging(); m_mouse.drag.start_position_3D = m_mouse.scene_position; m_sequential_print_clearance_first_displacement = true; -#if ENABLE_SINKING_CONTOURS - show_sinking_contours(); -#endif // ENABLE_SINKING_CONTOURS m_moving = true; } } @@ -3323,6 +3320,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else evt.Skip(); +#if ENABLE_SINKING_CONTOURS + if (m_moving) + show_sinking_contours(); +#endif // ENABLE_SINKING_CONTOURS + #ifdef __WXMSW__ if (on_enter_workaround) m_mouse.position = Vec2d(-1., -1.);