From 3c0e33136358c6f32ecf507c09021a7d72014dee Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 15 Nov 2022 12:17:18 +0100 Subject: [PATCH 01/99] Gizmo measure modified to accept single full instance selection, to combine the volumes meshes into a single mesh and pass it to the back end after transform it in world coordinates Changes embedded into tech ENABLE_GIZMO_MEASURE_WORLD_COORDINATES --- src/libslic3r/Measure.cpp | 37 ++++ src/libslic3r/Measure.hpp | 19 +- src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 215 ++++++++++++++++++++++- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 35 ++++ src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 13 ++ src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 7 + src/slic3r/GUI/Selection.cpp | 13 ++ src/slic3r/GUI/Selection.hpp | 4 + 9 files changed, 338 insertions(+), 7 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 43b9782a83..1ffd72c14d 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -45,6 +45,9 @@ public: std::optional get_feature(size_t face_idx, const Vec3d& point) const; std::vector> get_planes_triangle_indices() const; const std::vector& get_plane_features(unsigned int plane_id) const; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const TriangleMesh& get_mesh() const; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES private: void update_planes(); @@ -52,7 +55,11 @@ private: std::vector m_planes; std::vector m_face_to_plane; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + TriangleMesh m_mesh; +#else const indexed_triangle_set& m_its; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; @@ -61,7 +68,11 @@ private: MeasuringImpl::MeasuringImpl(const indexed_triangle_set& its) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +: m_mesh(its) +#else : m_its{its} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES { update_planes(); extract_features(); @@ -74,10 +85,17 @@ void MeasuringImpl::update_planes() // Now we'll go through all the facets and append Points of facets sharing the same normal. // This part is still performed in mesh coordinate system. +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const size_t num_of_facets = m_mesh.its.indices.size(); + m_face_to_plane.resize(num_of_facets, size_t(-1)); + const std::vector face_normals = its_face_normals(m_mesh.its); + const std::vector face_neighbors = its_face_neighbors(m_mesh.its); +#else const size_t num_of_facets = m_its.indices.size(); m_face_to_plane.resize(num_of_facets, size_t(-1)); const std::vector face_normals = its_face_normals(m_its); const std::vector face_neighbors = its_face_neighbors(m_its); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::vector facet_queue(num_of_facets, 0); int facet_queue_cnt = 0; const stl_normal* normal_ptr = nullptr; @@ -126,7 +144,11 @@ void MeasuringImpl::update_planes() assert(std::none_of(m_face_to_plane.begin(), m_face_to_plane.end(), [](size_t val) { return val == size_t(-1); })); // Now we will walk around each of the planes and save vertices which form the border. +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + SurfaceMesh sm(m_mesh.its); +#else SurfaceMesh sm(m_its); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES for (int plane_id=0; plane_id < int(m_planes.size()); ++plane_id) { const auto& facets = m_planes[plane_id].facets; m_planes[plane_id].borders.clear(); @@ -508,6 +530,12 @@ const std::vector& MeasuringImpl::get_plane_features(unsigned in return m_planes[plane_id].surface_features; } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +const TriangleMesh& MeasuringImpl::get_mesh() const +{ + return this->m_mesh; +} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES @@ -549,6 +577,13 @@ const std::vector& Measuring::get_plane_features(unsigned int pl return priv->get_plane_features(plane_id); } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +const TriangleMesh& Measuring::get_mesh() const +{ + return priv->get_mesh(); +} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const AngleAndEdges AngleAndEdges::Dummy = { 0.0, Vec3d::Zero(), { Vec3d::Zero(), Vec3d::Zero() }, { Vec3d::Zero(), Vec3d::Zero() }, 0.0, true }; static AngleAndEdges angle_edge_edge(const std::pair& e1, const std::pair& e2) @@ -1147,6 +1182,7 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& return result; } +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void DistAndPoints::transform(const Transform3d& trafo) { from = trafo * from; to = trafo * to; @@ -1167,6 +1203,7 @@ void AngleAndEdges::transform(const Transform3d& trafo) { const double average_scale = 0.5 * (new_e1.norm() / old_e1.norm() + new_e2.norm() / old_e2.norm()); radius = average_scale * radius; } +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index ede8c634ee..b2e2008d15 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -87,9 +87,11 @@ class MeasuringImpl; class Measuring { public: - // Construct the measurement object on a given its. The its must remain - // valid and unchanged during the whole lifetime of the object. - explicit Measuring(const indexed_triangle_set& its); + // Construct the measurement object on a given its. +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + // The its must remain valid and unchanged during the whole lifetime of the object. +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + explicit Measuring(const indexed_triangle_set& its); ~Measuring(); // Return a reference to a list of all features identified on the its. @@ -108,6 +110,11 @@ public: // Returns the surface features of the plane with the given index const std::vector& get_plane_features(unsigned int plane_id) const; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + // Returns the mesh used for measuring + const TriangleMesh& get_mesh() const; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + private: std::unique_ptr priv; }; @@ -119,7 +126,9 @@ struct DistAndPoints { Vec3d from; Vec3d to; +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void transform(const Transform3d& trafo); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; struct AngleAndEdges { @@ -132,7 +141,9 @@ struct AngleAndEdges { double radius; bool coplanar; +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void transform(const Transform3d& trafo); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES static const AngleAndEdges Dummy; }; @@ -151,6 +162,7 @@ struct MeasurementResult { return angle.has_value() || distance_infinite.has_value() || distance_strict.has_value() || distance_xyz.has_value(); } +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void transform(const Transform3d& trafo) { if (angle.has_value()) angle->transform(trafo); @@ -161,6 +173,7 @@ struct MeasurementResult { distance_xyz = (distance_strict->to - distance_strict->from).cwiseAbs(); } } +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; // Returns distance/angle between two SurfaceFeatures. diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index a3e72cf0c5..9e7c660ae0 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -64,6 +64,8 @@ // Enable picking using raytracing #define ENABLE_RAYCAST_PICKING (1 && ENABLE_LEGACY_OPENGL_REMOVAL) #define ENABLE_RAYCAST_PICKING_DEBUG (0 && ENABLE_RAYCAST_PICKING) +// Enable gizmo measure combining volumes meshes and passing them to the backend in world coordinates +#define ENABLE_GIZMO_MEASURE_WORLD_COORDINATES (1 && ENABLE_2_5_0_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 8b26422c8f..5ae906eac9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -5,9 +5,11 @@ #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/GUI_ObjectManipulation.hpp" -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" #include "libslic3r/Model.hpp" +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES #include "libslic3r/PresetBundle.hpp" #include "libslic3r/MeasureUtils.hpp" @@ -242,7 +244,10 @@ private: TransformHelper::Cache TransformHelper::s_cache = { { 0, 0, 0, 0 }, Matrix4d::Identity(), Transform3d::Identity() }; GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) - : GLGizmoBase(parent, icon_filename, sprite_id) +: GLGizmoBase(parent, icon_filename, sprite_id) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +, m_raycaster(nullptr) +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES { GLModel::Geometry sphere_geometry = smooth_sphere(16, 7.5f); m_sphere.mesh_raycaster = std::make_unique(std::make_shared(sphere_geometry.get_as_indexed_triangle_set())); @@ -370,8 +375,10 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) { m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // transform to world coordinates m_measurement_result.transform(m_volume_matrix); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } m_imgui->set_requires_extra_frame(); @@ -419,6 +426,9 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) void GLGizmoMeasure::data_changed() { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + update_if_needed(); +#else const Selection& selection = m_parent.get_selection(); const ModelObject* model_object = nullptr; const ModelVolume* model_volume = nullptr; @@ -429,13 +439,16 @@ void GLGizmoMeasure::data_changed() } if (model_object != m_old_model_object || model_volume != m_old_model_volume) update_if_needed(); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_last_inv_zoom = 0.0f; m_last_plane_idx = -1; if (m_pending_scale) { m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // transform to world coordinates m_measurement_result.transform(m_volume_matrix); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_pending_scale = false; } else @@ -512,6 +525,9 @@ void GLGizmoMeasure::on_set_state() m_editing_distance = false; m_is_editing_distance_first_frame = true; m_measuring.reset(); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + m_raycaster.release(); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } else { m_mode = EMode::FeatureSelection; @@ -528,10 +544,12 @@ void GLGizmoMeasure::on_set_state() } } +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES CommonGizmosDataID GLGizmoMeasure::on_get_requirements() const { return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo) | int(CommonGizmosDataID::Raycaster)); } +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::string GLGizmoMeasure::on_get_name() const { @@ -543,9 +561,15 @@ bool GLGizmoMeasure::on_is_activable() const const Selection& selection = m_parent.get_selection(); bool res = (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) ? selection.is_single_full_instance() : +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier(); + if (res) + res &= !selection.contains_sinking_volumes(); +#else selection.is_single_volume() || selection.is_single_volume_instance(); if (res) res &= !selection.get_first_volume()->is_sinking(); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES return res; } @@ -562,8 +586,10 @@ void GLGizmoMeasure::on_render() const Selection& selection = m_parent.get_selection(); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA && selection.is_single_full_instance()) || (selection.is_single_volume() || selection.is_single_volume_instance())) { +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES update_if_needed(); const Camera& camera = wxGetApp().plater()->get_camera(); @@ -572,7 +598,11 @@ void GLGizmoMeasure::on_render() Vec3f position_on_model; Vec3f normal_on_model; size_t model_facet_idx; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const bool mouse_on_object = m_raycaster.raycaster()->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); +#else const bool mouse_on_object = m_c->raycaster()->raycasters().front()->unproject_on_mesh(m_mouse_pos, m_volume_matrix, camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const bool is_hovering_on_feature = (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) && m_hover_id != -1; auto update_circle = [this, inv_zoom]() { @@ -581,7 +611,11 @@ void GLGizmoMeasure::on_render() m_last_circle = m_curr_feature; m_circle.reset(); const auto [center, radius, normal] = m_curr_feature->get_circle(); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); +#else GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), m_volume_matrix.cast()); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_circle.mesh_raycaster = std::make_unique(std::make_shared(circle_geometry.get_as_indexed_triangle_set())); m_circle.model.init_from(std::move(circle_geometry)); return true; @@ -639,7 +673,11 @@ void GLGizmoMeasure::on_render() const auto [idx, normal, point] = m_curr_feature->get_plane(); if (m_last_plane_idx != idx) { m_last_plane_idx = idx; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const indexed_triangle_set& its = m_measuring->get_mesh().its; +#else const indexed_triangle_set its = (m_old_model_volume != nullptr) ? m_old_model_volume->mesh().its : m_old_model_object->volumes.front()->mesh().its; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const std::vector> planes_triangles = m_measuring->get_planes_triangle_indices(); GLModel::Geometry init_data = init_plane_data(its, planes_triangles, idx); m_plane.reset(); @@ -689,12 +727,20 @@ void GLGizmoMeasure::on_render() if (extra.has_value() && m_hover_id == POINT_ID) m_curr_point_on_feature_position = *extra; else +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + m_curr_point_on_feature_position = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); +#else m_curr_point_on_feature_position = m_volume_matrix.inverse() * position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES break; } case Measure::SurfaceFeatureType::Plane: { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + m_curr_point_on_feature_position = position_on_feature(PLANE_ID, camera); +#else m_curr_point_on_feature_position = m_volume_matrix.inverse() * position_on_feature(PLANE_ID, camera); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES break; } case Measure::SurfaceFeatureType::Circle: @@ -704,9 +750,17 @@ void GLGizmoMeasure::on_render() m_curr_point_on_feature_position = center; else { const Vec3d world_pof = position_on_feature(CIRCLE_ID, camera, [](const Vec3f& v) { return v; }); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Eigen::Hyperplane plane(normal, center); +#else const Eigen::Hyperplane plane(m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal, m_volume_matrix * center); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Transform3d local_to_model_matrix = Geometry::translation_transform(center) * Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), normal); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Vec3d local_proj = local_to_model_matrix.inverse() * plane.projection(world_pof); +#else const Vec3d local_proj = local_to_model_matrix.inverse() * m_volume_matrix.inverse() * plane.projection(world_pof); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES double angle = std::atan2(local_proj.y(), local_proj.x()); if (angle < 0.0) angle += 2.0 * double(M_PI); @@ -767,8 +821,12 @@ void GLGizmoMeasure::on_render() default: { assert(false); break; } case Measure::SurfaceFeatureType::Point: { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d feature_matrix = Geometry::translation_transform(feature.get_point()) * Geometry::scale_transform(inv_zoom); +#else const Vec3d position = TransformHelper::model_to_world(feature.get_point(), m_volume_matrix); const Transform3d feature_matrix = Geometry::translation_transform(position) * Geometry::scale_transform(inv_zoom); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(feature_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); @@ -785,8 +843,12 @@ void GLGizmoMeasure::on_render() const auto& [center, radius, normal] = feature.get_circle(); // render center if (update_raycasters_transform) { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d center_matrix = Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom); +#else const Vec3d center_world = TransformHelper::model_to_world(center, m_volume_matrix); const Transform3d center_matrix = Geometry::translation_transform(center_world) * Geometry::scale_transform(inv_zoom); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(center_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); @@ -809,7 +871,11 @@ void GLGizmoMeasure::on_render() } else { GLModel circle; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); +#else GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), m_volume_matrix.cast()); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES circle.init_from(std::move(circle_geometry)); set_emission_uniform(colors.back(), hover); circle.set_color(colors.back()); @@ -825,8 +891,12 @@ void GLGizmoMeasure::on_render() if (update_raycasters_transform) { const std::optional extra = feature.get_extra_point(); if (extra.has_value()) { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d point_matrix = Geometry::translation_transform(*extra) * Geometry::scale_transform(inv_zoom); +#else const Vec3d extra_world = TransformHelper::model_to_world(*extra, m_volume_matrix); const Transform3d point_matrix = Geometry::translation_transform(extra_world) * Geometry::scale_transform(inv_zoom); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(point_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); @@ -838,11 +908,17 @@ void GLGizmoMeasure::on_render() } // render edge if (m_mode != EMode::CenterSelection) { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d edge_matrix = Geometry::translation_transform(from) * + Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * + Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); +#else const Vec3d from_world = TransformHelper::model_to_world(from, m_volume_matrix); const Vec3d to_world = TransformHelper::model_to_world(to, m_volume_matrix); const Transform3d edge_matrix = Geometry::translation_transform(from_world) * Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to_world - from_world) * Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to_world - from_world).norm() }); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(edge_matrix); set_emission_uniform(colors.back(), hover); m_cylinder.model.set_color(colors.back()); @@ -861,7 +937,11 @@ void GLGizmoMeasure::on_render() if (colors.front() != m_parent.get_selection().get_first_volume()->render_color) { const auto& [idx, normal, pt] = feature.get_plane(); assert(idx < m_plane_models_cache.size()); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + set_matrix_uniforms(Transform3d::Identity()); +#else set_matrix_uniforms(m_volume_matrix); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_emission_uniform(colors.front(), hover); m_plane_models_cache[idx].set_color(colors.front()); m_plane_models_cache[idx].render(); @@ -869,7 +949,11 @@ void GLGizmoMeasure::on_render() if (update_raycasters_transform) { auto it = m_raycasters.find(PLANE_ID); if (it != m_raycasters.end() && it->second != nullptr) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + it->second->set_transform(Transform3d::Identity()); +#else it->second->set_transform(m_volume_matrix); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } break; } @@ -924,7 +1008,11 @@ void GLGizmoMeasure::on_render() auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_1_ID; }); if (it != m_selection_raycasters.end()) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + (*it)->set_transform(Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); +#else (*it)->set_transform(m_volume_matrix * Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } } if (m_selected_features.second.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.second.feature)) { @@ -934,14 +1022,22 @@ void GLGizmoMeasure::on_render() auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); if (it != m_selection_raycasters.end()) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + (*it)->set_transform(Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); +#else (*it)->set_transform(m_volume_matrix * Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } } if (is_hovering_on_feature && m_curr_point_on_feature_position.has_value()) { if (m_hover_id != POINT_ID) { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d matrix = Geometry::translation_transform(*m_curr_point_on_feature_position) * Geometry::scale_transform(inv_zoom); +#else const Vec3d position = TransformHelper::model_to_world(*m_curr_point_on_feature_position, m_volume_matrix); const Transform3d matrix = Geometry::translation_transform(position) * Geometry::scale_transform(inv_zoom); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(matrix); const ColorRGBA color = hover_selection_color(); set_emission_uniform(color, true); @@ -954,7 +1050,9 @@ void GLGizmoMeasure::on_render() if (old_cullface) glsafe(::glEnable(GL_CULL_FACE)); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES render_dimensioning(); } @@ -971,6 +1069,24 @@ void GLGizmoMeasure::update_if_needed() } }; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + auto do_update = [this, update_plane_models_cache](const std::vector& volumes_cache, const Selection& selection) { + TriangleMesh composite_mesh; + for (const auto& vol : volumes_cache) { +// if (selection.is_single_full_instance() && vol.volume->is_modifier()) +// continue; + + TriangleMesh volume_mesh = vol.volume->mesh(); + volume_mesh.transform(vol.instance->get_transformation().get_matrix() * vol.volume->get_transformation().get_matrix()); + composite_mesh.merge(volume_mesh); + } + + m_measuring.reset(new Measure::Measuring(composite_mesh.its)); + update_plane_models_cache(m_measuring->get_mesh().its); + m_raycaster.update_from(m_measuring->get_mesh()); + m_volumes_cache = volumes_cache; + }; +#else auto do_update = [this, update_plane_models_cache](const ModelObject* object, const ModelVolume* volume) { const indexed_triangle_set& its = (volume != nullptr) ? volume->mesh().its : object->volumes.front()->mesh().its; m_measuring.reset(new Measure::Measuring(its)); @@ -980,24 +1096,44 @@ void GLGizmoMeasure::update_if_needed() // Let's save what we calculated it from: m_volumes_matrices.clear(); m_volumes_types.clear(); - m_first_instance_scale = Vec3d::Ones(); + m_first_instance_scale = Vec3d::Ones(); m_first_instance_mirror = Vec3d::Ones(); if (object != nullptr) { for (const ModelVolume* vol : object->volumes) { m_volumes_matrices.push_back(vol->get_matrix()); m_volumes_types.push_back(vol->type()); } - m_first_instance_scale = object->instances.front()->get_scaling_factor(); + m_first_instance_scale = object->instances.front()->get_scaling_factor(); m_first_instance_mirror = object->instances.front()->get_mirror(); } m_old_model_object = object; m_old_model_volume = volume; }; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Selection& selection = m_parent.get_selection(); if (selection.is_empty()) return; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Selection::IndicesList& idxs = selection.get_volume_idxs(); + std::vector volumes_cache; + volumes_cache.reserve(idxs.size()); + for (unsigned int idx : idxs) { + const GLVolume* v = selection.get_volume(idx); + const ModelObject* obj = selection.get_model()->objects[v->object_idx()]; + const ModelInstance* inst = obj->instances[v->instance_idx()]; + const ModelVolume* vol = obj->volumes[v->volume_idx()]; + const VolumeCacheItem item = { obj, inst, vol, inst->get_matrix() * vol->get_matrix() }; + volumes_cache.emplace_back(item); + } + + if (m_state != On || volumes_cache.empty()) + return; + + if (m_measuring == nullptr || m_volumes_cache != volumes_cache) + do_update(volumes_cache, selection); +#else m_volume_matrix = selection.get_first_volume()->world_matrix(); const ModelObject* mo = m_c->selection_info()->model_object(); @@ -1026,6 +1162,7 @@ void GLGizmoMeasure::update_if_needed() break; } } +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } void GLGizmoMeasure::disable_scene_raycasters() @@ -1145,6 +1282,62 @@ void GLGizmoMeasure::render_dimensioning() const double ratio = new_value / old_value; wxGetApp().plater()->take_snapshot(_L("Scale")); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + struct TrafoData + { + double ratio; + Vec3d old_pivot; + Vec3d new_pivot; + Transform3d scale_matrix; + + TrafoData(double ratio, const Vec3d& pivot) { + this->ratio = ratio; + this->scale_matrix = Geometry::scale_transform(ratio); + this->old_pivot = pivot; + this->new_pivot = { pivot.x(), pivot.y(), (this->scale_matrix * pivot).z() }; + } + + Vec3d transform(const Vec3d& point) const { + return this->scale_matrix * (point - this->old_pivot) + this->new_pivot; + } + }; + + auto scale_feature = [this](Measure::SurfaceFeature& feature, const TrafoData& trafo_data) { + switch (feature.get_type()) + { + case Measure::SurfaceFeatureType::Point: + { + feature = Measure::SurfaceFeature(trafo_data.transform(feature.get_point())); + break; + } + case Measure::SurfaceFeatureType::Edge: + { + const auto [from, to] = feature.get_edge(); + const std::optional extra = feature.get_extra_point(); + const std::optional new_extra = extra.has_value() ? trafo_data.transform(*extra) : extra; + feature = Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, trafo_data.transform(from), trafo_data.transform(to), new_extra); + break; + } + case Measure::SurfaceFeatureType::Circle: + { + const auto [center, radius, normal] = feature.get_circle(); + feature = Measure::SurfaceFeature(Measure::SurfaceFeatureType::Circle, trafo_data.transform(center), normal, std::nullopt, trafo_data.ratio * radius); + break; + } + case Measure::SurfaceFeatureType::Plane: + { + const auto [idx, normal, origin] = feature.get_plane(); + feature = Measure::SurfaceFeature(Measure::SurfaceFeatureType::Plane, normal, trafo_data.transform(origin), std::nullopt, idx); + break; + } + } + }; + + const TrafoData trafo_data(ratio, m_parent.get_selection().get_bounding_box().center()); + scale_feature(*m_selected_features.first.feature, trafo_data); + scale_feature(*m_selected_features.second.feature, trafo_data); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + TransformationType type; type.set_world(); type.set_relative(); @@ -1203,8 +1396,10 @@ void GLGizmoMeasure::render_dimensioning() assert(f1.get_type() == Measure::SurfaceFeatureType::Point && f2.get_type() == Measure::SurfaceFeatureType::Edge); std::pair e = f2.get_edge(); // Transform to world coordinates +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES e.first = TransformHelper::model_to_world(e.first, m_volume_matrix); e.second = TransformHelper::model_to_world(e.second, m_volume_matrix); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Vec3d v_proj = m_measurement_result.distance_infinite->to; @@ -1485,15 +1680,21 @@ void GLGizmoMeasure::render_debug_dialog() { case Measure::SurfaceFeatureType::Point: { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(item.feature->get_point()), ImGui::GetStyleColorVec4(ImGuiCol_Text)); +#else const Vec3d position = m_volume_matrix * item.feature->get_point(); add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(position), ImGui::GetStyleColorVec4(ImGuiCol_Text)); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES break; } case Measure::SurfaceFeatureType::Edge: { auto [from, to] = item.feature->get_edge(); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES from = m_volume_matrix * from; to = m_volume_matrix * to; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(from), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(to), ImGui::GetStyleColorVec4(ImGuiCol_Text)); break; @@ -1501,8 +1702,10 @@ void GLGizmoMeasure::render_debug_dialog() case Measure::SurfaceFeatureType::Plane: { auto [idx, normal, origin] = item.feature->get_plane(); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES origin = m_volume_matrix * origin; normal = m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(origin), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_value", ImGuiWrapper::COL_ORANGE_LIGHT, format_double(idx), ImGui::GetStyleColorVec4(ImGuiCol_Text)); @@ -1511,9 +1714,13 @@ void GLGizmoMeasure::render_debug_dialog() case Measure::SurfaceFeatureType::Circle: { auto [center, radius, normal] = item.feature->get_circle(); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); +#else const Vec3d on_circle = m_volume_matrix * (center + radius * Measure::get_orthogonal(normal, true)); center = m_volume_matrix * center; normal = (m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal).normalized(); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES radius = (on_circle - center).norm(); add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(center), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 7bfc2e8c93..606012f7c4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -5,10 +5,16 @@ #include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GUI_Utils.hpp" #include "libslic3r/Measure.hpp" +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" +#include "libslic3r/Model.hpp" +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES namespace Slic3r { +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES class ModelVolume; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES enum class ModelVolumeType : int; @@ -68,6 +74,23 @@ class GLGizmoMeasure : public GLGizmoBase } }; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + struct VolumeCacheItem + { + const ModelObject* object{ nullptr }; + const ModelInstance* instance{ nullptr }; + const ModelVolume* volume{ nullptr }; + Transform3d world_trafo; + + bool operator == (const VolumeCacheItem& other) const { + return this->object == other.object && this->instance == other.instance && this->volume == other.volume && + this->world_trafo.isApprox(other.world_trafo); + } + }; + + std::vector m_volumes_cache; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + EMode m_mode{ EMode::FeatureSelection }; Measure::MeasurementResult m_measurement_result; @@ -85,7 +108,13 @@ class GLGizmoMeasure : public GLGizmoBase }; Dimensioning m_dimensioning; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + // Uses a standalone raycaster and not the shared one because of the + // difference in how the mesh is updated + CommonGizmosDataObjects::Raycaster m_raycaster; +#else Transform3d m_volume_matrix{ Transform3d::Identity() }; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::vector m_plane_models_cache; std::map> m_raycasters; std::vector> m_selection_raycasters; @@ -100,17 +129,21 @@ class GLGizmoMeasure : public GLGizmoBase std::vector m_scene_raycasters; // These hold information to decide whether recalculation is necessary: +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::vector m_volumes_matrices; std::vector m_volumes_types; Vec3d m_first_instance_scale{ Vec3d::Ones() }; Vec3d m_first_instance_mirror{ Vec3d::Ones() }; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES float m_last_inv_zoom{ 0.0f }; std::optional m_last_circle; int m_last_plane_idx{ -1 }; bool m_mouse_left_down{ false }; // for detection left_up of this gizmo +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const ModelObject* m_old_model_object{ nullptr }; const ModelVolume* m_old_model_volume{ nullptr }; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES Vec2d m_mouse_pos{ Vec2d::Zero() }; @@ -153,7 +186,9 @@ protected: bool on_is_activable() const override; void on_render() override; void on_set_state() override; +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES CommonGizmosDataID on_get_requirements() const override; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES virtual void on_render_input_window(float x, float y, float bottom_limit) override; virtual void on_register_raycasters_for_picking() override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 394e879b7c..dca64a5266 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -327,6 +327,19 @@ const TriangleMesh* HollowedMesh::get_hollowed_interior() const } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +void Raycaster::update_from(const TriangleMesh& mesh) +{ + std::vector meshes = { &mesh }; + if (meshes != m_old_meshes) { + wxBusyCursor wait; + m_raycasters.clear(); + m_raycasters.emplace_back(new MeshRaycaster(std::make_shared(mesh))); + m_old_meshes = meshes; + } + validate(); +} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void Raycaster::on_update() diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 42faa25f84..b02e3a920c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -137,6 +137,9 @@ protected: virtual void on_update() = 0; CommonGizmosDataPool* get_pool() const { return m_common; } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + void validate() { m_is_valid = true; } +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES private: bool m_is_valid = false; @@ -242,6 +245,10 @@ public: const MeshRaycaster* raycaster() const { assert(m_raycasters.size() == 1); return m_raycasters.front().get(); } std::vector raycasters() const; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + void update_from(const TriangleMesh& mesh); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + protected: void on_update() override; void on_release() override; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 9a4169b318..2e50fc37c9 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -602,6 +602,19 @@ bool Selection::contains_any_volume(const std::vector& volume_idxs return false; } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +bool Selection::contains_sinking_volumes(bool ignore_modifiers) const +{ + for (const GLVolume* v : *m_volumes) { + if (!ignore_modifiers || !v->is_modifier) { + if (v->is_sinking()) + return true; + } + } + return false; +} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + bool Selection::matches(const std::vector& volume_idxs) const { unsigned int count = 0; diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index c4720a3081..0064f27999 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -337,6 +337,10 @@ public: bool contains_all_volumes(const std::vector& volume_idxs) const; // returns true if the selection contains at least one of the given indices bool contains_any_volume(const std::vector& volume_idxs) const; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + // returns true if the selection contains any sinking volume + bool contains_sinking_volumes(bool ignore_modifiers = true) const; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // returns true if the selection contains all and only the given indices bool matches(const std::vector& volume_idxs) const; From 182e5ece2e47547a243962d518a667b40b3556d8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 15 Nov 2022 12:42:22 +0100 Subject: [PATCH 02/99] Added missing declaration --- src/libslic3r/Measure.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index b2e2008d15..9cc380dd2b 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -12,6 +12,11 @@ struct indexed_triangle_set; namespace Slic3r { + +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +class TriangleMesh; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + namespace Measure { From c98ba0e651d63fc277e879232276adce0bdd49c9 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 15 Nov 2022 16:07:38 +0100 Subject: [PATCH 03/99] Measurement: refactoring - do not touch common raycaster interface when there is no need --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 9 +++------ src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 15 --------------- src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 8 -------- 4 files changed, 5 insertions(+), 31 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 5ae906eac9..8cfbf634eb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -245,9 +245,6 @@ TransformHelper::Cache TransformHelper::s_cache = { { 0, 0, 0, 0 }, Matrix4d::Id GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -, m_raycaster(nullptr) -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES { GLModel::Geometry sphere_geometry = smooth_sphere(16, 7.5f); m_sphere.mesh_raycaster = std::make_unique(std::make_shared(sphere_geometry.get_as_indexed_triangle_set())); @@ -526,7 +523,7 @@ void GLGizmoMeasure::on_set_state() m_is_editing_distance_first_frame = true; m_measuring.reset(); #if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - m_raycaster.release(); + m_raycaster.reset(); #endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } else { @@ -599,7 +596,7 @@ void GLGizmoMeasure::on_render() Vec3f normal_on_model; size_t model_facet_idx; #if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const bool mouse_on_object = m_raycaster.raycaster()->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); + const bool mouse_on_object = m_raycaster->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); #else const bool mouse_on_object = m_c->raycaster()->raycasters().front()->unproject_on_mesh(m_mouse_pos, m_volume_matrix, camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); #endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES @@ -1083,7 +1080,7 @@ void GLGizmoMeasure::update_if_needed() m_measuring.reset(new Measure::Measuring(composite_mesh.its)); update_plane_models_cache(m_measuring->get_mesh().its); - m_raycaster.update_from(m_measuring->get_mesh()); + m_raycaster.reset(new MeshRaycaster(std::make_shared(m_measuring->get_mesh()))); m_volumes_cache = volumes_cache; }; #else diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 606012f7c4..fbbf30da78 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -4,9 +4,9 @@ #include "GLGizmoBase.hpp" #include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GUI_Utils.hpp" +#include "slic3r/GUI/MeshUtils.hpp" #include "libslic3r/Measure.hpp" #if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" #include "libslic3r/Model.hpp" #endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES @@ -111,7 +111,7 @@ class GLGizmoMeasure : public GLGizmoBase #if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // Uses a standalone raycaster and not the shared one because of the // difference in how the mesh is updated - CommonGizmosDataObjects::Raycaster m_raycaster; + std::unique_ptr m_raycaster; #else Transform3d m_volume_matrix{ Transform3d::Identity() }; #endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index dca64a5266..11c44113bc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -327,21 +327,6 @@ const TriangleMesh* HollowedMesh::get_hollowed_interior() const } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -void Raycaster::update_from(const TriangleMesh& mesh) -{ - std::vector meshes = { &mesh }; - if (meshes != m_old_meshes) { - wxBusyCursor wait; - m_raycasters.clear(); - m_raycasters.emplace_back(new MeshRaycaster(std::make_shared(mesh))); - m_old_meshes = meshes; - } - validate(); -} -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - - void Raycaster::on_update() { wxBusyCursor wait; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index b02e3a920c..3878c6b25a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -137,10 +137,6 @@ protected: virtual void on_update() = 0; CommonGizmosDataPool* get_pool() const { return m_common; } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void validate() { m_is_valid = true; } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - private: bool m_is_valid = false; CommonGizmosDataPool* m_common = nullptr; @@ -245,10 +241,6 @@ public: const MeshRaycaster* raycaster() const { assert(m_raycasters.size() == 1); return m_raycasters.front().get(); } std::vector raycasters() const; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void update_from(const TriangleMesh& mesh); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - protected: void on_update() override; void on_release() override; From 6dac9f2aca0439fef6af8e6c0f6b0d6a77788b03 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 15 Nov 2022 16:08:27 +0100 Subject: [PATCH 04/99] Measurement: Partially fixed the common gizmo raycaster for self-intersecting meshes --- src/slic3r/GUI/MeshUtils.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index e33d29ba16..3805151af1 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -409,6 +409,12 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& Vec3d direction; line_from_mouse_pos(mouse_pos, trafo, camera, point, direction); + if (rand()%100 == 0) { + int a=5; + int b=6; + int c=7; + } + std::vector hits = m_emesh.query_ray_hits(point, direction); if (hits.empty()) @@ -429,10 +435,10 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& // All hits are clipped. return false; } - if ((hits.size()-i) % 2 != 0) { + if (clipping_plane && (hits.size()-i) % 2 != 0) { // There is an odd number of unclipped hits - meaning the nearest must be from inside the mesh. // In that case, calculate intersection with the clipping place. - if (clipping_plane && was_clipping_plane_hit) { + if (was_clipping_plane_hit) { direction = direction + point; point = trafo * point; // transform to world coords direction = trafo * direction - point; From c24ce158054bf23daaca10499799cbd946dca15b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 08:53:02 +0100 Subject: [PATCH 05/99] Tech ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set as default --- src/libslic3r/Measure.cpp | 48 -- src/libslic3r/Measure.hpp | 30 +- src/libslic3r/Technologies.hpp | 2 - src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 850 +++++++++-------------- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 26 +- src/slic3r/GUI/Selection.cpp | 2 - src/slic3r/GUI/Selection.hpp | 2 - 7 files changed, 323 insertions(+), 637 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 1ffd72c14d..cea9f0b77e 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -45,9 +45,7 @@ public: std::optional get_feature(size_t face_idx, const Vec3d& point) const; std::vector> get_planes_triangle_indices() const; const std::vector& get_plane_features(unsigned int plane_id) const; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const TriangleMesh& get_mesh() const; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES private: void update_planes(); @@ -55,11 +53,7 @@ private: std::vector m_planes; std::vector m_face_to_plane; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES TriangleMesh m_mesh; -#else - const indexed_triangle_set& m_its; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; @@ -68,11 +62,7 @@ private: MeasuringImpl::MeasuringImpl(const indexed_triangle_set& its) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES : m_mesh(its) -#else -: m_its{its} -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES { update_planes(); extract_features(); @@ -85,17 +75,10 @@ void MeasuringImpl::update_planes() // Now we'll go through all the facets and append Points of facets sharing the same normal. // This part is still performed in mesh coordinate system. -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const size_t num_of_facets = m_mesh.its.indices.size(); m_face_to_plane.resize(num_of_facets, size_t(-1)); const std::vector face_normals = its_face_normals(m_mesh.its); const std::vector face_neighbors = its_face_neighbors(m_mesh.its); -#else - const size_t num_of_facets = m_its.indices.size(); - m_face_to_plane.resize(num_of_facets, size_t(-1)); - const std::vector face_normals = its_face_normals(m_its); - const std::vector face_neighbors = its_face_neighbors(m_its); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::vector facet_queue(num_of_facets, 0); int facet_queue_cnt = 0; const stl_normal* normal_ptr = nullptr; @@ -144,11 +127,7 @@ void MeasuringImpl::update_planes() assert(std::none_of(m_face_to_plane.begin(), m_face_to_plane.end(), [](size_t val) { return val == size_t(-1); })); // Now we will walk around each of the planes and save vertices which form the border. -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES SurfaceMesh sm(m_mesh.its); -#else - SurfaceMesh sm(m_its); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES for (int plane_id=0; plane_id < int(m_planes.size()); ++plane_id) { const auto& facets = m_planes[plane_id].facets; m_planes[plane_id].borders.clear(); @@ -530,12 +509,10 @@ const std::vector& MeasuringImpl::get_plane_features(unsigned in return m_planes[plane_id].surface_features; } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const TriangleMesh& MeasuringImpl::get_mesh() const { return this->m_mesh; } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES @@ -577,12 +554,10 @@ const std::vector& Measuring::get_plane_features(unsigned int pl return priv->get_plane_features(plane_id); } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const TriangleMesh& Measuring::get_mesh() const { return priv->get_mesh(); } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const AngleAndEdges AngleAndEdges::Dummy = { 0.0, Vec3d::Zero(), { Vec3d::Zero(), Vec3d::Zero() }, { Vec3d::Zero(), Vec3d::Zero() }, 0.0, true }; @@ -1182,29 +1157,6 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& return result; } -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -void DistAndPoints::transform(const Transform3d& trafo) { - from = trafo * from; - to = trafo * to; - dist = (to - from).norm(); -} - -void AngleAndEdges::transform(const Transform3d& trafo) { - const Vec3d old_e1 = e1.second - e1.first; - const Vec3d old_e2 = e2.second - e2.first; - center = trafo * center; - e1.first = trafo * e1.first; - e1.second = trafo * e1.second; - e2.first = trafo * e2.first; - e2.second = trafo * e2.second; - angle = std::acos(std::clamp(Measure::edge_direction(e1).dot(Measure::edge_direction(e2)), -1.0, 1.0)); - const Vec3d new_e1 = e1.second - e1.first; - const Vec3d new_e2 = e2.second - e2.first; - const double average_scale = 0.5 * (new_e1.norm() / old_e1.norm() + new_e2.norm() / old_e2.norm()); - radius = average_scale * radius; -} -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index 9cc380dd2b..3a1a4b89d9 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -13,9 +13,7 @@ struct indexed_triangle_set; namespace Slic3r { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES class TriangleMesh; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES namespace Measure { @@ -93,10 +91,7 @@ class MeasuringImpl; class Measuring { public: // Construct the measurement object on a given its. -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - // The its must remain valid and unchanged during the whole lifetime of the object. -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - explicit Measuring(const indexed_triangle_set& its); + explicit Measuring(const indexed_triangle_set& its); ~Measuring(); // Return a reference to a list of all features identified on the its. @@ -115,10 +110,8 @@ public: // Returns the surface features of the plane with the given index const std::vector& get_plane_features(unsigned int plane_id) const; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // Returns the mesh used for measuring const TriangleMesh& get_mesh() const; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES private: std::unique_ptr priv; @@ -130,10 +123,6 @@ struct DistAndPoints { double dist; Vec3d from; Vec3d to; - -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void transform(const Transform3d& trafo); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; struct AngleAndEdges { @@ -146,10 +135,6 @@ struct AngleAndEdges { double radius; bool coplanar; -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void transform(const Transform3d& trafo); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - static const AngleAndEdges Dummy; }; @@ -166,19 +151,6 @@ struct MeasurementResult { bool has_any_data() const { return angle.has_value() || distance_infinite.has_value() || distance_strict.has_value() || distance_xyz.has_value(); } - -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void transform(const Transform3d& trafo) { - if (angle.has_value()) - angle->transform(trafo); - if (distance_infinite.has_value()) - distance_infinite->transform(trafo); - if (distance_strict.has_value()) { - distance_strict->transform(trafo); - distance_xyz = (distance_strict->to - distance_strict->from).cwiseAbs(); - } - } -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; // Returns distance/angle between two SurfaceFeatures. diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 9e7c660ae0..a3e72cf0c5 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -64,8 +64,6 @@ // Enable picking using raytracing #define ENABLE_RAYCAST_PICKING (1 && ENABLE_LEGACY_OPENGL_REMOVAL) #define ENABLE_RAYCAST_PICKING_DEBUG (0 && ENABLE_RAYCAST_PICKING) -// Enable gizmo measure combining volumes meshes and passing them to the backend in world coordinates -#define ENABLE_GIZMO_MEASURE_WORLD_COORDINATES (1 && ENABLE_2_5_0_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 8cfbf634eb..35767121d7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -6,10 +6,6 @@ #include "slic3r/GUI/GUI_ObjectManipulation.hpp" -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" -#include "libslic3r/Model.hpp" -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES #include "libslic3r/PresetBundle.hpp" #include "libslic3r/MeasureUtils.hpp" @@ -370,13 +366,8 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) } } - if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) { + if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - // transform to world coordinates - m_measurement_result.transform(m_volume_matrix); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - } m_imgui->set_requires_extra_frame(); @@ -423,29 +414,12 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) void GLGizmoMeasure::data_changed() { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES update_if_needed(); -#else - const Selection& selection = m_parent.get_selection(); - const ModelObject* model_object = nullptr; - const ModelVolume* model_volume = nullptr; - if (selection.is_single_full_instance() || - selection.is_from_single_object() ) { - model_object = selection.get_model()->objects[selection.get_object_idx()]; - model_volume = model_object->volumes[selection.get_first_volume()->volume_idx()]; - } - if (model_object != m_old_model_object || model_volume != m_old_model_volume) - update_if_needed(); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_last_inv_zoom = 0.0f; m_last_plane_idx = -1; if (m_pending_scale) { m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - // transform to world coordinates - m_measurement_result.transform(m_volume_matrix); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_pending_scale = false; } else @@ -522,9 +496,7 @@ void GLGizmoMeasure::on_set_state() m_editing_distance = false; m_is_editing_distance_first_frame = true; m_measuring.reset(); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_raycaster.reset(); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } else { m_mode = EMode::FeatureSelection; @@ -541,13 +513,6 @@ void GLGizmoMeasure::on_set_state() } } -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -CommonGizmosDataID GLGizmoMeasure::on_get_requirements() const -{ - return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo) | int(CommonGizmosDataID::Raycaster)); -} -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - std::string GLGizmoMeasure::on_get_name() const { return _u8L("Measure"); @@ -558,15 +523,9 @@ bool GLGizmoMeasure::on_is_activable() const const Selection& selection = m_parent.get_selection(); bool res = (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) ? selection.is_single_full_instance() : -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier(); if (res) res &= !selection.contains_sinking_volumes(); -#else - selection.is_single_volume() || selection.is_single_volume_instance(); - if (res) - res &= !selection.get_first_volume()->is_sinking(); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES return res; } @@ -583,473 +542,390 @@ void GLGizmoMeasure::on_render() const Selection& selection = m_parent.get_selection(); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA && selection.is_single_full_instance()) || - (selection.is_single_volume() || selection.is_single_volume_instance())) { -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - update_if_needed(); + update_if_needed(); - const Camera& camera = wxGetApp().plater()->get_camera(); - const float inv_zoom = (float)camera.get_inv_zoom(); + const Camera& camera = wxGetApp().plater()->get_camera(); + const float inv_zoom = (float)camera.get_inv_zoom(); - Vec3f position_on_model; - Vec3f normal_on_model; - size_t model_facet_idx; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const bool mouse_on_object = m_raycaster->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); -#else - const bool mouse_on_object = m_c->raycaster()->raycasters().front()->unproject_on_mesh(m_mouse_pos, m_volume_matrix, camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const bool is_hovering_on_feature = (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) && m_hover_id != -1; + Vec3f position_on_model; + Vec3f normal_on_model; + size_t model_facet_idx; + const bool mouse_on_object = m_raycaster->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); + const bool is_hovering_on_feature = (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) && m_hover_id != -1; - auto update_circle = [this, inv_zoom]() { - if (m_last_inv_zoom != inv_zoom || m_last_circle != m_curr_feature) { - m_last_inv_zoom = inv_zoom; - m_last_circle = m_curr_feature; - m_circle.reset(); - const auto [center, radius, normal] = m_curr_feature->get_circle(); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); -#else - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), m_volume_matrix.cast()); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - m_circle.mesh_raycaster = std::make_unique(std::make_shared(circle_geometry.get_as_indexed_triangle_set())); - m_circle.model.init_from(std::move(circle_geometry)); - return true; - } - return false; - }; + auto update_circle = [this, inv_zoom]() { + if (m_last_inv_zoom != inv_zoom || m_last_circle != m_curr_feature) { + m_last_inv_zoom = inv_zoom; + m_last_circle = m_curr_feature; + m_circle.reset(); + const auto [center, radius, normal] = m_curr_feature->get_circle(); + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); + m_circle.mesh_raycaster = std::make_unique(std::make_shared(circle_geometry.get_as_indexed_triangle_set())); + m_circle.model.init_from(std::move(circle_geometry)); + return true; + } + return false; + }; - if (m_mode == EMode::FeatureSelection || m_mode == EMode::PointSelection) { - if ((m_hover_id == SELECTION_1_ID && boost::algorithm::istarts_with(m_selected_features.first.source, _u8L("Center"))) || - (m_hover_id == SELECTION_2_ID && boost::algorithm::istarts_with(m_selected_features.second.source, _u8L("Center")))) { - // Skip feature detection if hovering on a selected center - m_curr_feature.reset(); + if (m_mode == EMode::FeatureSelection || m_mode == EMode::PointSelection) { + if ((m_hover_id == SELECTION_1_ID && boost::algorithm::istarts_with(m_selected_features.first.source, _u8L("Center"))) || + (m_hover_id == SELECTION_2_ID && boost::algorithm::istarts_with(m_selected_features.second.source, _u8L("Center")))) { + // Skip feature detection if hovering on a selected center + m_curr_feature.reset(); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); + m_curr_point_on_feature_position.reset(); + } + else { + std::optional curr_feature = mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; + if (m_curr_feature != curr_feature || + (curr_feature.has_value() && curr_feature->get_type() == Measure::SurfaceFeatureType::Circle && (m_curr_feature != curr_feature || m_last_inv_zoom != inv_zoom))) { m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); - m_curr_point_on_feature_position.reset(); - } - else { - std::optional curr_feature = mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; - if (m_curr_feature != curr_feature || - (curr_feature.has_value() && curr_feature->get_type() == Measure::SurfaceFeatureType::Circle && (m_curr_feature != curr_feature || m_last_inv_zoom != inv_zoom))) { - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID); - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID); - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); - m_raycasters.clear(); - m_curr_feature = curr_feature; - if (!m_curr_feature.has_value()) - return; + m_raycasters.clear(); + m_curr_feature = curr_feature; + if (!m_curr_feature.has_value()) + return; - switch (m_curr_feature->get_type()) { - default: { assert(false); break; } - case Measure::SurfaceFeatureType::Point: - { - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); - break; - } - case Measure::SurfaceFeatureType::Edge: - { - m_raycasters.insert({ EDGE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID, *m_cylinder.mesh_raycaster) }); - if (m_curr_feature->get_extra_point().has_value()) - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); - break; - } - case Measure::SurfaceFeatureType::Circle: - { - update_circle(); - m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); - break; - } - case Measure::SurfaceFeatureType::Plane: - { - const auto [idx, normal, point] = m_curr_feature->get_plane(); - if (m_last_plane_idx != idx) { - m_last_plane_idx = idx; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const indexed_triangle_set& its = m_measuring->get_mesh().its; -#else - const indexed_triangle_set its = (m_old_model_volume != nullptr) ? m_old_model_volume->mesh().its : m_old_model_object->volumes.front()->mesh().its; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const std::vector> planes_triangles = m_measuring->get_planes_triangle_indices(); - GLModel::Geometry init_data = init_plane_data(its, planes_triangles, idx); - m_plane.reset(); - m_plane.mesh_raycaster = std::make_unique(std::make_shared(init_data.get_as_indexed_triangle_set())); - m_plane.model.init_from(std::move(init_data)); - } - - m_raycasters.insert({ PLANE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID, *m_plane.mesh_raycaster) }); - break; - } - } - } - } - } - - if (m_mode != EMode::PointSelection) - m_curr_point_on_feature_position.reset(); - else if (is_hovering_on_feature) { - auto position_on_feature = [this](int feature_type_id, const Camera& camera, std::function callback = nullptr) -> Vec3d { - auto it = m_raycasters.find(feature_type_id); - if (it != m_raycasters.end() && it->second != nullptr) { - Vec3f p; - Vec3f n; - const Transform3d& trafo = it->second->get_transform(); - bool res = it->second->get_raycaster()->closest_hit(m_mouse_pos, trafo, camera, p, n); - if (res) { - if (callback) - p = callback(p); - return trafo * p.cast(); - } - } - return Vec3d::Zero(); - }; - - if (m_curr_feature.has_value()) { - switch (m_curr_feature->get_type()) - { + switch (m_curr_feature->get_type()) { default: { assert(false); break; } case Measure::SurfaceFeatureType::Point: { - m_curr_point_on_feature_position = m_curr_feature->get_point(); + m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); break; } case Measure::SurfaceFeatureType::Edge: { - const std::optional extra = m_curr_feature->get_extra_point(); - if (extra.has_value() && m_hover_id == POINT_ID) - m_curr_point_on_feature_position = *extra; - else -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - m_curr_point_on_feature_position = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); -#else - m_curr_point_on_feature_position = m_volume_matrix.inverse() * position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + m_raycasters.insert({ EDGE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID, *m_cylinder.mesh_raycaster) }); + if (m_curr_feature->get_extra_point().has_value()) + m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); + break; + } + case Measure::SurfaceFeatureType::Circle: + { + update_circle(); + m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); + m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); break; } case Measure::SurfaceFeatureType::Plane: { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - m_curr_point_on_feature_position = position_on_feature(PLANE_ID, camera); -#else - m_curr_point_on_feature_position = m_volume_matrix.inverse() * position_on_feature(PLANE_ID, camera); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - break; - } - case Measure::SurfaceFeatureType::Circle: - { - const auto [center, radius, normal] = m_curr_feature->get_circle(); - if (m_hover_id == POINT_ID) - m_curr_point_on_feature_position = center; - else { - const Vec3d world_pof = position_on_feature(CIRCLE_ID, camera, [](const Vec3f& v) { return v; }); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Eigen::Hyperplane plane(normal, center); -#else - const Eigen::Hyperplane plane(m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal, m_volume_matrix * center); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d local_to_model_matrix = Geometry::translation_transform(center) * Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), normal); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Vec3d local_proj = local_to_model_matrix.inverse() * plane.projection(world_pof); -#else - const Vec3d local_proj = local_to_model_matrix.inverse() * m_volume_matrix.inverse() * plane.projection(world_pof); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - double angle = std::atan2(local_proj.y(), local_proj.x()); - if (angle < 0.0) - angle += 2.0 * double(M_PI); - - const Vec3d local_pos = radius * Vec3d(std::cos(angle), std::sin(angle), 0.0); - m_curr_point_on_feature_position = local_to_model_matrix * local_pos; + const auto [idx, normal, point] = m_curr_feature->get_plane(); + if (m_last_plane_idx != idx) { + m_last_plane_idx = idx; + const indexed_triangle_set& its = m_measuring->get_mesh().its; + const std::vector> planes_triangles = m_measuring->get_planes_triangle_indices(); + GLModel::Geometry init_data = init_plane_data(its, planes_triangles, idx); + m_plane.reset(); + m_plane.mesh_raycaster = std::make_unique(std::make_shared(init_data.get_as_indexed_triangle_set())); + m_plane.model.init_from(std::move(init_data)); } + + m_raycasters.insert({ PLANE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID, *m_plane.mesh_raycaster) }); break; } } } } - else { - if (m_curr_feature.has_value() && m_curr_feature->get_type() == Measure::SurfaceFeatureType::Circle) { - if (update_circle()) { - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); - auto it = m_raycasters.find(CIRCLE_ID); - if (it != m_raycasters.end()) - m_raycasters.erase(it); - m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); + } + + if (m_mode != EMode::PointSelection) + m_curr_point_on_feature_position.reset(); + else if (is_hovering_on_feature) { + auto position_on_feature = [this](int feature_type_id, const Camera& camera, std::function callback = nullptr) -> Vec3d { + auto it = m_raycasters.find(feature_type_id); + if (it != m_raycasters.end() && it->second != nullptr) { + Vec3f p; + Vec3f n; + const Transform3d& trafo = it->second->get_transform(); + bool res = it->second->get_raycaster()->closest_hit(m_mouse_pos, trafo, camera, p, n); + if (res) { + if (callback) + p = callback(p); + return trafo * p.cast(); } } + return Vec3d::Zero(); + }; + + if (m_curr_feature.has_value()) { + switch (m_curr_feature->get_type()) + { + default: { assert(false); break; } + case Measure::SurfaceFeatureType::Point: + { + m_curr_point_on_feature_position = m_curr_feature->get_point(); + break; + } + case Measure::SurfaceFeatureType::Edge: + { + const std::optional extra = m_curr_feature->get_extra_point(); + if (extra.has_value() && m_hover_id == POINT_ID) + m_curr_point_on_feature_position = *extra; + else + m_curr_point_on_feature_position = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); + break; + } + case Measure::SurfaceFeatureType::Plane: + { + m_curr_point_on_feature_position = position_on_feature(PLANE_ID, camera); + break; + } + case Measure::SurfaceFeatureType::Circle: + { + const auto [center, radius, normal] = m_curr_feature->get_circle(); + if (m_hover_id == POINT_ID) + m_curr_point_on_feature_position = center; + else { + const Vec3d world_pof = position_on_feature(CIRCLE_ID, camera, [](const Vec3f& v) { return v; }); + const Eigen::Hyperplane plane(normal, center); + const Transform3d local_to_model_matrix = Geometry::translation_transform(center) * Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), normal); + const Vec3d local_proj = local_to_model_matrix.inverse() * plane.projection(world_pof); + double angle = std::atan2(local_proj.y(), local_proj.x()); + if (angle < 0.0) + angle += 2.0 * double(M_PI); + + const Vec3d local_pos = radius * Vec3d(std::cos(angle), std::sin(angle), 0.0); + m_curr_point_on_feature_position = local_to_model_matrix * local_pos; + } + break; + } + } } + } + else { + if (m_curr_feature.has_value() && m_curr_feature->get_type() == Measure::SurfaceFeatureType::Circle) { + if (update_circle()) { + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); + auto it = m_raycasters.find(CIRCLE_ID); + if (it != m_raycasters.end()) + m_raycasters.erase(it); + m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); + } + } + } - if (!m_curr_feature.has_value() && !m_selected_features.first.feature.has_value()) - return; + if (!m_curr_feature.has_value() && !m_selected_features.first.feature.has_value()) + return; - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); - if (shader == nullptr) - return; + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; - shader->start_using(); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->start_using(); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_DEPTH_TEST)); - const bool old_cullface = ::glIsEnabled(GL_CULL_FACE); - glsafe(::glDisable(GL_CULL_FACE)); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_DEPTH_TEST)); + const bool old_cullface = ::glIsEnabled(GL_CULL_FACE); + glsafe(::glDisable(GL_CULL_FACE)); - const Transform3d& view_matrix = camera.get_view_matrix(); + const Transform3d& view_matrix = camera.get_view_matrix(); - auto set_matrix_uniforms = [shader, &view_matrix](const Transform3d& model_matrix) { - const Transform3d view_model_matrix = view_matrix * model_matrix; - shader->set_uniform("view_model_matrix", view_model_matrix); - const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); - shader->set_uniform("view_normal_matrix", view_normal_matrix); - }; + auto set_matrix_uniforms = [shader, &view_matrix](const Transform3d& model_matrix) { + const Transform3d view_model_matrix = view_matrix * model_matrix; + shader->set_uniform("view_model_matrix", view_model_matrix); + const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); + shader->set_uniform("view_normal_matrix", view_normal_matrix); + }; - auto set_emission_uniform = [this, shader](const ColorRGBA& color, bool hover) { - shader->set_uniform("emission_factor", (color == m_parent.get_selection().get_first_volume()->render_color) ? 0.0f : - hover ? 0.5f : 0.25f); - }; + auto set_emission_uniform = [this, shader](const ColorRGBA& color, bool hover) { + shader->set_uniform("emission_factor", (color == m_parent.get_selection().get_first_volume()->render_color) ? 0.0f : + hover ? 0.5f : 0.25f); + }; - auto render_feature = [this, set_matrix_uniforms, set_emission_uniform](const Measure::SurfaceFeature& feature, const std::vector& colors, - float inv_zoom, bool hover, bool update_raycasters_transform) { - switch (feature.get_type()) - { - default: { assert(false); break; } - case Measure::SurfaceFeatureType::Point: - { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d feature_matrix = Geometry::translation_transform(feature.get_point()) * Geometry::scale_transform(inv_zoom); -#else - const Vec3d position = TransformHelper::model_to_world(feature.get_point(), m_volume_matrix); - const Transform3d feature_matrix = Geometry::translation_transform(position) * Geometry::scale_transform(inv_zoom); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(feature_matrix); + auto render_feature = [this, set_matrix_uniforms, set_emission_uniform](const Measure::SurfaceFeature& feature, const std::vector& colors, + float inv_zoom, bool hover, bool update_raycasters_transform) { + switch (feature.get_type()) + { + default: { assert(false); break; } + case Measure::SurfaceFeatureType::Point: + { + const Transform3d feature_matrix = Geometry::translation_transform(feature.get_point()) * Geometry::scale_transform(inv_zoom); + set_matrix_uniforms(feature_matrix); + set_emission_uniform(colors.front(), hover); + m_sphere.model.set_color(colors.front()); + m_sphere.model.render(); + if (update_raycasters_transform) { + auto it = m_raycasters.find(POINT_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(feature_matrix); + } + break; + } + case Measure::SurfaceFeatureType::Circle: + { + const auto& [center, radius, normal] = feature.get_circle(); + // render center + if (update_raycasters_transform) { + const Transform3d center_matrix = Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom); + set_matrix_uniforms(center_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); m_sphere.model.render(); - if (update_raycasters_transform) { - auto it = m_raycasters.find(POINT_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(feature_matrix); - } - break; + auto it = m_raycasters.find(POINT_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(center_matrix); } - case Measure::SurfaceFeatureType::Circle: - { - const auto& [center, radius, normal] = feature.get_circle(); - // render center + // render circle + if (m_mode != EMode::CenterSelection) { + const Transform3d circle_matrix = Transform3d::Identity(); + set_matrix_uniforms(circle_matrix); if (update_raycasters_transform) { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d center_matrix = Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom); -#else - const Vec3d center_world = TransformHelper::model_to_world(center, m_volume_matrix); - const Transform3d center_matrix = Geometry::translation_transform(center_world) * Geometry::scale_transform(inv_zoom); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(center_matrix); + set_emission_uniform(colors.back(), hover); + m_circle.model.set_color(colors.back()); + m_circle.model.render(); + auto it = m_raycasters.find(CIRCLE_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(circle_matrix); + } + else { + GLModel circle; + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); + circle.init_from(std::move(circle_geometry)); + set_emission_uniform(colors.back(), hover); + circle.set_color(colors.back()); + circle.render(); + } + } + break; + } + case Measure::SurfaceFeatureType::Edge: + { + const auto& [from, to] = feature.get_edge(); + // render extra point + if (update_raycasters_transform) { + const std::optional extra = feature.get_extra_point(); + if (extra.has_value()) { + const Transform3d point_matrix = Geometry::translation_transform(*extra) * Geometry::scale_transform(inv_zoom); + set_matrix_uniforms(point_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); m_sphere.model.render(); auto it = m_raycasters.find(POINT_ID); if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(center_matrix); + it->second->set_transform(point_matrix); } - // render circle - if (m_mode != EMode::CenterSelection) { - const Transform3d circle_matrix = Transform3d::Identity(); - set_matrix_uniforms(circle_matrix); - if (update_raycasters_transform) { - set_emission_uniform(colors.back(), hover); - m_circle.model.set_color(colors.back()); - m_circle.model.render(); - auto it = m_raycasters.find(CIRCLE_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(circle_matrix); - } - else { - GLModel circle; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); -#else - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), m_volume_matrix.cast()); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - circle.init_from(std::move(circle_geometry)); - set_emission_uniform(colors.back(), hover); - circle.set_color(colors.back()); - circle.render(); - } - } - break; } - case Measure::SurfaceFeatureType::Edge: - { - const auto& [from, to] = feature.get_edge(); - // render extra point + // render edge + if (m_mode != EMode::CenterSelection) { + const Transform3d edge_matrix = Geometry::translation_transform(from) * + Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * + Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); + set_matrix_uniforms(edge_matrix); + set_emission_uniform(colors.back(), hover); + m_cylinder.model.set_color(colors.back()); + m_cylinder.model.render(); if (update_raycasters_transform) { - const std::optional extra = feature.get_extra_point(); - if (extra.has_value()) { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d point_matrix = Geometry::translation_transform(*extra) * Geometry::scale_transform(inv_zoom); -#else - const Vec3d extra_world = TransformHelper::model_to_world(*extra, m_volume_matrix); - const Transform3d point_matrix = Geometry::translation_transform(extra_world) * Geometry::scale_transform(inv_zoom); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(point_matrix); - set_emission_uniform(colors.front(), hover); - m_sphere.model.set_color(colors.front()); - m_sphere.model.render(); - auto it = m_raycasters.find(POINT_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(point_matrix); - } - } - // render edge - if (m_mode != EMode::CenterSelection) { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d edge_matrix = Geometry::translation_transform(from) * - Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * - Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); -#else - const Vec3d from_world = TransformHelper::model_to_world(from, m_volume_matrix); - const Vec3d to_world = TransformHelper::model_to_world(to, m_volume_matrix); - const Transform3d edge_matrix = Geometry::translation_transform(from_world) * - Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to_world - from_world) * - Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to_world - from_world).norm() }); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(edge_matrix); - set_emission_uniform(colors.back(), hover); - m_cylinder.model.set_color(colors.back()); - m_cylinder.model.render(); - if (update_raycasters_transform) { - auto it = m_raycasters.find(EDGE_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(edge_matrix); - } - } - break; - } - case Measure::SurfaceFeatureType::Plane: - { - // no need to render the plane in case it is rendered with the same color as the volume in the 3D scene - if (colors.front() != m_parent.get_selection().get_first_volume()->render_color) { - const auto& [idx, normal, pt] = feature.get_plane(); - assert(idx < m_plane_models_cache.size()); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(Transform3d::Identity()); -#else - set_matrix_uniforms(m_volume_matrix); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_emission_uniform(colors.front(), hover); - m_plane_models_cache[idx].set_color(colors.front()); - m_plane_models_cache[idx].render(); - } - if (update_raycasters_transform) { - auto it = m_raycasters.find(PLANE_ID); + auto it = m_raycasters.find(EDGE_ID); if (it != m_raycasters.end() && it->second != nullptr) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - it->second->set_transform(Transform3d::Identity()); -#else - it->second->set_transform(m_volume_matrix); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + it->second->set_transform(edge_matrix); } - break; } + break; + } + case Measure::SurfaceFeatureType::Plane: + { + // no need to render the plane in case it is rendered with the same color as the volume in the 3D scene + if (colors.front() != m_parent.get_selection().get_first_volume()->render_color) { + const auto& [idx, normal, pt] = feature.get_plane(); + assert(idx < m_plane_models_cache.size()); + set_matrix_uniforms(Transform3d::Identity()); + set_emission_uniform(colors.front(), hover); + m_plane_models_cache[idx].set_color(colors.front()); + m_plane_models_cache[idx].render(); } - }; + if (update_raycasters_transform) { + auto it = m_raycasters.find(PLANE_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(Transform3d::Identity()); + } + break; + } + } + }; - auto hover_selection_color = [this]() { - return !m_selected_features.first.feature.has_value() ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; - }; + auto hover_selection_color = [this]() { + return !m_selected_features.first.feature.has_value() ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; + }; - auto hovering_color = [this, hover_selection_color, &selection]() { - return (m_mode == EMode::PointSelection) ? selection.get_first_volume()->render_color : hover_selection_color(); - }; + auto hovering_color = [this, hover_selection_color, &selection]() { + return (m_mode == EMode::PointSelection) ? selection.get_first_volume()->render_color : hover_selection_color(); + }; - if (m_curr_feature.has_value()) { - std::vector colors; - if (m_selected_features.first.feature.has_value() && *m_curr_feature == *m_selected_features.first.feature) + if (m_curr_feature.has_value()) { + std::vector colors; + if (m_selected_features.first.feature.has_value() && *m_curr_feature == *m_selected_features.first.feature) + colors.emplace_back(hovering_color()); + else if (m_selected_features.second.feature.has_value() && *m_curr_feature == *m_selected_features.second.feature) + colors.emplace_back(hovering_color()); + else { + switch (m_curr_feature->get_type()) + { + default: { assert(false); break; } + case Measure::SurfaceFeatureType::Point: + { + colors.emplace_back(hover_selection_color()); + break; + } + case Measure::SurfaceFeatureType::Edge: + case Measure::SurfaceFeatureType::Circle: + { + colors.emplace_back((m_hover_id == POINT_ID) ? hover_selection_color() : hovering_color()); colors.emplace_back(hovering_color()); - else if (m_selected_features.second.feature.has_value() && *m_curr_feature == *m_selected_features.second.feature) + break; + } + case Measure::SurfaceFeatureType::Plane: + { colors.emplace_back(hovering_color()); - else { - switch (m_curr_feature->get_type()) - { - default: { assert(false); break; } - case Measure::SurfaceFeatureType::Point: - { - colors.emplace_back(hover_selection_color()); - break; - } - case Measure::SurfaceFeatureType::Edge: - case Measure::SurfaceFeatureType::Circle: - { - colors.emplace_back((m_hover_id == POINT_ID) ? hover_selection_color() : hovering_color()); - colors.emplace_back(hovering_color()); - break; - } - case Measure::SurfaceFeatureType::Plane: - { - colors.emplace_back(hovering_color()); - break; - } - } + break; } - - render_feature(*m_curr_feature, colors, inv_zoom, true, true); - } - - if (m_selected_features.first.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.first.feature)) { - const std::vector colors = { SELECTED_1ST_COLOR }; - render_feature(*m_selected_features.first.feature, colors, inv_zoom, m_hover_id == SELECTION_1_ID, false); - if (m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Point) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_1_ID; }); - if (it != m_selection_raycasters.end()) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - (*it)->set_transform(Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); -#else - (*it)->set_transform(m_volume_matrix * Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - } - } - if (m_selected_features.second.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.second.feature)) { - const std::vector colors = { SELECTED_2ND_COLOR }; - render_feature(*m_selected_features.second.feature, colors, inv_zoom, m_hover_id == SELECTION_2_ID, false); - if (m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Point) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); - if (it != m_selection_raycasters.end()) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - (*it)->set_transform(Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); -#else - (*it)->set_transform(m_volume_matrix * Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } } - if (is_hovering_on_feature && m_curr_point_on_feature_position.has_value()) { - if (m_hover_id != POINT_ID) { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d matrix = Geometry::translation_transform(*m_curr_point_on_feature_position) * Geometry::scale_transform(inv_zoom); -#else - const Vec3d position = TransformHelper::model_to_world(*m_curr_point_on_feature_position, m_volume_matrix); - const Transform3d matrix = Geometry::translation_transform(position) * Geometry::scale_transform(inv_zoom); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(matrix); - const ColorRGBA color = hover_selection_color(); - set_emission_uniform(color, true); - m_sphere.model.set_color(color); - m_sphere.model.render(); - } - } - - shader->stop_using(); - - if (old_cullface) - glsafe(::glEnable(GL_CULL_FACE)); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + render_feature(*m_curr_feature, colors, inv_zoom, true, true); } -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + + if (m_selected_features.first.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.first.feature)) { + const std::vector colors = { SELECTED_1ST_COLOR }; + render_feature(*m_selected_features.first.feature, colors, inv_zoom, m_hover_id == SELECTION_1_ID, false); + if (m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Point) { + auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), + [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_1_ID; }); + if (it != m_selection_raycasters.end()) + (*it)->set_transform(Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); + } + } + if (m_selected_features.second.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.second.feature)) { + const std::vector colors = { SELECTED_2ND_COLOR }; + render_feature(*m_selected_features.second.feature, colors, inv_zoom, m_hover_id == SELECTION_2_ID, false); + if (m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Point) { + auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), + [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); + if (it != m_selection_raycasters.end()) + (*it)->set_transform(Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); + } + } + + if (is_hovering_on_feature && m_curr_point_on_feature_position.has_value()) { + if (m_hover_id != POINT_ID) { + const Transform3d matrix = Geometry::translation_transform(*m_curr_point_on_feature_position) * Geometry::scale_transform(inv_zoom); + set_matrix_uniforms(matrix); + const ColorRGBA color = hover_selection_color(); + set_emission_uniform(color, true); + m_sphere.model.set_color(color); + m_sphere.model.render(); + } + } + + shader->stop_using(); + + if (old_cullface) + glsafe(::glEnable(GL_CULL_FACE)); render_dimensioning(); } @@ -1066,7 +942,6 @@ void GLGizmoMeasure::update_if_needed() } }; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES auto do_update = [this, update_plane_models_cache](const std::vector& volumes_cache, const Selection& selection) { TriangleMesh composite_mesh; for (const auto& vol : volumes_cache) { @@ -1083,36 +958,11 @@ void GLGizmoMeasure::update_if_needed() m_raycaster.reset(new MeshRaycaster(std::make_shared(m_measuring->get_mesh()))); m_volumes_cache = volumes_cache; }; -#else - auto do_update = [this, update_plane_models_cache](const ModelObject* object, const ModelVolume* volume) { - const indexed_triangle_set& its = (volume != nullptr) ? volume->mesh().its : object->volumes.front()->mesh().its; - m_measuring.reset(new Measure::Measuring(its)); - - update_plane_models_cache(its); - - // Let's save what we calculated it from: - m_volumes_matrices.clear(); - m_volumes_types.clear(); - m_first_instance_scale = Vec3d::Ones(); - m_first_instance_mirror = Vec3d::Ones(); - if (object != nullptr) { - for (const ModelVolume* vol : object->volumes) { - m_volumes_matrices.push_back(vol->get_matrix()); - m_volumes_types.push_back(vol->type()); - } - m_first_instance_scale = object->instances.front()->get_scaling_factor(); - m_first_instance_mirror = object->instances.front()->get_mirror(); - } - m_old_model_object = object; - m_old_model_volume = volume; - }; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Selection& selection = m_parent.get_selection(); if (selection.is_empty()) return; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Selection::IndicesList& idxs = selection.get_volume_idxs(); std::vector volumes_cache; volumes_cache.reserve(idxs.size()); @@ -1130,36 +980,6 @@ void GLGizmoMeasure::update_if_needed() if (m_measuring == nullptr || m_volumes_cache != volumes_cache) do_update(volumes_cache, selection); -#else - m_volume_matrix = selection.get_first_volume()->world_matrix(); - - const ModelObject* mo = m_c->selection_info()->model_object(); - const ModelVolume* mv = m_c->selection_info()->model_volume(); - if (m_state != On || (mo == nullptr && mv == nullptr)) - return; - - if (mo == nullptr) - mo = mv->get_object(); - - if (mo->instances.empty()) - return; - - if (!m_measuring || mo != m_old_model_object || mv != m_old_model_volume || mo->volumes.size() != m_volumes_matrices.size()) - do_update(mo, mv); - - // We want to recalculate when the scale changes - some planes could (dis)appear. - if (!mo->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale) || - !mo->instances.front()->get_mirror().isApprox(m_first_instance_mirror)) - do_update(mo, mv); - - for (unsigned int i = 0; i < mo->volumes.size(); ++i) { - if (!mo->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i]) || - mo->volumes[i]->type() != m_volumes_types[i]) { - do_update(mo, mv); - break; - } - } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } void GLGizmoMeasure::disable_scene_raycasters() @@ -1279,7 +1099,6 @@ void GLGizmoMeasure::render_dimensioning() const double ratio = new_value / old_value; wxGetApp().plater()->take_snapshot(_L("Scale")); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES struct TrafoData { double ratio; @@ -1333,7 +1152,6 @@ void GLGizmoMeasure::render_dimensioning() const TrafoData trafo_data(ratio, m_parent.get_selection().get_bounding_box().center()); scale_feature(*m_selected_features.first.feature, trafo_data); scale_feature(*m_selected_features.second.feature, trafo_data); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES TransformationType type; type.set_world(); @@ -1392,14 +1210,7 @@ void GLGizmoMeasure::render_dimensioning() auto point_edge = [this, shader](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2) { assert(f1.get_type() == Measure::SurfaceFeatureType::Point && f2.get_type() == Measure::SurfaceFeatureType::Edge); std::pair e = f2.get_edge(); - // Transform to world coordinates -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - e.first = TransformHelper::model_to_world(e.first, m_volume_matrix); - e.second = TransformHelper::model_to_world(e.second, m_volume_matrix); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Vec3d v_proj = m_measurement_result.distance_infinite->to; - const Vec3d e1e2 = e.second - e.first; const Vec3d v_proje1 = v_proj - e.first; const bool on_e1_side = v_proje1.dot(e1e2) < -EPSILON; @@ -1677,21 +1488,12 @@ void GLGizmoMeasure::render_debug_dialog() { case Measure::SurfaceFeatureType::Point: { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(item.feature->get_point()), ImGui::GetStyleColorVec4(ImGuiCol_Text)); -#else - const Vec3d position = m_volume_matrix * item.feature->get_point(); - add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(position), ImGui::GetStyleColorVec4(ImGuiCol_Text)); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES break; } case Measure::SurfaceFeatureType::Edge: { auto [from, to] = item.feature->get_edge(); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - from = m_volume_matrix * from; - to = m_volume_matrix * to; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(from), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(to), ImGui::GetStyleColorVec4(ImGuiCol_Text)); break; @@ -1699,10 +1501,6 @@ void GLGizmoMeasure::render_debug_dialog() case Measure::SurfaceFeatureType::Plane: { auto [idx, normal, origin] = item.feature->get_plane(); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - origin = m_volume_matrix * origin; - normal = m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(origin), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_value", ImGuiWrapper::COL_ORANGE_LIGHT, format_double(idx), ImGui::GetStyleColorVec4(ImGuiCol_Text)); @@ -1711,13 +1509,7 @@ void GLGizmoMeasure::render_debug_dialog() case Measure::SurfaceFeatureType::Circle: { auto [center, radius, normal] = item.feature->get_circle(); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); -#else - const Vec3d on_circle = m_volume_matrix * (center + radius * Measure::get_orthogonal(normal, true)); - center = m_volume_matrix * center; - normal = (m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal).normalized(); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES radius = (on_circle - center).norm(); add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(center), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index fbbf30da78..9699d73cc8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -6,16 +6,10 @@ #include "slic3r/GUI/GUI_Utils.hpp" #include "slic3r/GUI/MeshUtils.hpp" #include "libslic3r/Measure.hpp" -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES #include "libslic3r/Model.hpp" -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES namespace Slic3r { -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -class ModelVolume; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - enum class ModelVolumeType : int; namespace Measure { class Measuring; } @@ -74,7 +68,6 @@ class GLGizmoMeasure : public GLGizmoBase } }; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES struct VolumeCacheItem { const ModelObject* object{ nullptr }; @@ -89,7 +82,6 @@ class GLGizmoMeasure : public GLGizmoBase }; std::vector m_volumes_cache; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES EMode m_mode{ EMode::FeatureSelection }; Measure::MeasurementResult m_measurement_result; @@ -108,13 +100,10 @@ class GLGizmoMeasure : public GLGizmoBase }; Dimensioning m_dimensioning; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // Uses a standalone raycaster and not the shared one because of the // difference in how the mesh is updated std::unique_ptr m_raycaster; -#else - Transform3d m_volume_matrix{ Transform3d::Identity() }; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + std::vector m_plane_models_cache; std::map> m_raycasters; std::vector> m_selection_raycasters; @@ -129,21 +118,11 @@ class GLGizmoMeasure : public GLGizmoBase std::vector m_scene_raycasters; // These hold information to decide whether recalculation is necessary: -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - std::vector m_volumes_matrices; - std::vector m_volumes_types; - Vec3d m_first_instance_scale{ Vec3d::Ones() }; - Vec3d m_first_instance_mirror{ Vec3d::Ones() }; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES float m_last_inv_zoom{ 0.0f }; std::optional m_last_circle; int m_last_plane_idx{ -1 }; bool m_mouse_left_down{ false }; // for detection left_up of this gizmo -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const ModelObject* m_old_model_object{ nullptr }; - const ModelVolume* m_old_model_volume{ nullptr }; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES Vec2d m_mouse_pos{ Vec2d::Zero() }; @@ -186,9 +165,6 @@ protected: bool on_is_activable() const override; void on_render() override; void on_set_state() override; -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - CommonGizmosDataID on_get_requirements() const override; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES virtual void on_render_input_window(float x, float y, float bottom_limit) override; virtual void on_register_raycasters_for_picking() override; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 2e50fc37c9..ee06e008b9 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -602,7 +602,6 @@ bool Selection::contains_any_volume(const std::vector& volume_idxs return false; } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES bool Selection::contains_sinking_volumes(bool ignore_modifiers) const { for (const GLVolume* v : *m_volumes) { @@ -613,7 +612,6 @@ bool Selection::contains_sinking_volumes(bool ignore_modifiers) const } return false; } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES bool Selection::matches(const std::vector& volume_idxs) const { diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 0064f27999..080acda0d1 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -337,10 +337,8 @@ public: bool contains_all_volumes(const std::vector& volume_idxs) const; // returns true if the selection contains at least one of the given indices bool contains_any_volume(const std::vector& volume_idxs) const; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // returns true if the selection contains any sinking volume bool contains_sinking_volumes(bool ignore_modifiers = true) const; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // returns true if the selection contains all and only the given indices bool matches(const std::vector& volume_idxs) const; From 45e6dbab8fc3b023a800918734832c032ac977e1 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 09:38:19 +0100 Subject: [PATCH 06/99] Gizmo measure - Fixed orientation of arrows in arc dimensioning --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index e35dc79fd2..e4973287e6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1292,7 +1292,7 @@ void GLGizmoMeasure::render_dimensioning() const double angle = (endpoint_id == 1) ? 0.0 : step * double(resolution); const Vec3d position_model = Geometry::translation_transform(center) * (draw_radius * (Eigen::Quaternion(Eigen::AngleAxisd(angle, normal)) * e1_unit)); const Vec3d direction_model = (endpoint_id == 1) ? -normal.cross(position_model - center).normalized() : normal.cross(position_model - center).normalized(); - const auto qz = Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), normal); + const auto qz = Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), (endpoint_id == 1) ? normal : -normal); const auto qx = Eigen::Quaternion::FromTwoVectors(qz * Vec3d::UnitX(), direction_model); const Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::translation_transform(position_model) * qx * qz * Geometry::scale_transform(camera.get_inv_zoom()); From 5e6041823873055e55d9286d2a6df9c421046053 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 09:42:55 +0100 Subject: [PATCH 07/99] Fixed warnings --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index e4973287e6..23b130d282 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1115,7 +1115,7 @@ void GLGizmoMeasure::render_dimensioning() } }; - auto scale_feature = [this](Measure::SurfaceFeature& feature, const TrafoData& trafo_data) { + auto scale_feature = [](Measure::SurfaceFeature& feature, const TrafoData& trafo_data) { switch (feature.get_type()) { case Measure::SurfaceFeatureType::Point: @@ -1143,6 +1143,7 @@ void GLGizmoMeasure::render_dimensioning() feature = Measure::SurfaceFeature(Measure::SurfaceFeatureType::Plane, normal, trafo_data.transform(origin), std::nullopt, idx); break; } + default: { break; } } }; From 2c2f10beb7855654ff1289e8adbd39b917108806 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 09:46:50 +0100 Subject: [PATCH 08/99] Fixed warnings --- src/libslic3r/Measure.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index cea9f0b77e..e3cd61cd1d 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -289,14 +289,14 @@ void MeasuringImpl::extract_features() // point happened to be inside the segment. The discrimination of too small segments // will follow, so we need a complete picture before that. if (circles_idxs.size() > 1 - && circles_idxs.back().second == angles.size()-1 + && circles_idxs.back().second == (int)angles.size()-1 && circles_idxs.front().first == 0) { // Possibly the same circle. Check that the angle and length criterion holds along the combined segment. bool same = true; double last_len = -1.; double last_angle = 0.; for (int i=circles_idxs.back().first + 1; i != circles_idxs.front().second; ++i) { - if (i == angles.size()) + if (i == (int)angles.size()) i = 1; if (last_len == -1.) { last_len = lengths[i]; @@ -345,12 +345,12 @@ void MeasuringImpl::extract_features() for (int i=int(circles_idxs.size())-1; i>=0; --i) { const auto& [start, end] = circles_idxs[i]; int N = start >= 0 - ? end - start + (start == 0 && end == border.size()-1 ? 0 : 1) // last point is the same as first + ? end - start + (start == 0 && end == (int)border.size()-1 ? 0 : 1) // last point is the same as first : end + (border.size() + start); if (N < 5) { circles.erase(circles.begin() + i); circles_idxs.erase(circles_idxs.begin() + i); - } else if (N <= 8 && start == 0 && end == border.size()-1) { + } else if (N <= 8 && start == 0 && end == (int)border.size()-1) { // This is a regular 5-8 polygon. Add the edges as edges with a special // point and remove the circle. Leave the indices in circles_idxs, so // the edges are not picked up again later. From 692573abf112e6b797cfa291cadec3c03544e9b9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 10:04:25 +0100 Subject: [PATCH 09/99] Removed debug code --- src/slic3r/GUI/MeshUtils.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 3805151af1..ba16aad251 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -409,12 +409,6 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& Vec3d direction; line_from_mouse_pos(mouse_pos, trafo, camera, point, direction); - if (rand()%100 == 0) { - int a=5; - int b=6; - int c=7; - } - std::vector hits = m_emesh.query_ray_hits(point, direction); if (hits.empty()) From 1f0fbd500afd7f41e5e84426fdbcb9b0c3f281f9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 12:04:38 +0100 Subject: [PATCH 10/99] Gizmo measure - Fixed angle for perpendicular edge-plane use case --- src/libslic3r/Measure.cpp | 53 +++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index e3cd61cd1d..535b898cf4 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -27,6 +27,21 @@ static std::pair get_center_and_radius(const std::vector& return std::make_pair(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius); } +static std::array orthonormal_basis(const Vec3d& v) +{ + std::array ret; + ret[2] = v.normalized(); + int index; + ret[2].maxCoeff(&index); + switch (index) + { + case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; } + case 1: { ret[0] = Vec3d(0.0, ret[2].z(), -ret[2].y()).normalized(); break; } + case 2: { ret[0] = Vec3d(-ret[2].z(), 0.0, ret[2].x()).normalized(); break; } + } + ret[1] = ret[2].cross(ret[0]).normalized(); + return ret; +} @@ -628,8 +643,8 @@ static AngleAndEdges angle_edge_edge(const std::pair& e1, const st static AngleAndEdges angle_edge_plane(const std::pair& e, const std::tuple& p) { const auto& [idx, normal, origin] = p; - const Vec3d e1e2_unit = edge_direction(e); - if (are_parallel(e1e2_unit, normal) || are_perpendicular(e1e2_unit, normal)) + Vec3d e1e2_unit = edge_direction(e); + if (are_perpendicular(e1e2_unit, normal)) return AngleAndEdges::Dummy; // ensure the edge is pointing away from the intersection @@ -641,8 +656,22 @@ static AngleAndEdges angle_edge_plane(const std::pair& e, const st // then verify edge direction and revert it, if needed Vec3d e1 = e.first; Vec3d e2 = e.second; - if ((e1 - inters).squaredNorm() > (e2 - inters).squaredNorm()) + if ((e1 - inters).squaredNorm() > (e2 - inters).squaredNorm()) { std::swap(e1, e2); + e1e2_unit = -e1e2_unit; + } + + if (are_parallel(e1e2_unit, normal)) { + const std::array basis = orthonormal_basis(e1e2_unit); + const double radius = (0.5 * (e1 + e2) - inters).norm(); + const Vec3d edge_on_plane_dir = (basis[1].dot(origin - inters) >= 0.0) ? basis[1] : -basis[1]; + std::pair edge_on_plane = std::make_pair(inters, inters + radius * edge_on_plane_dir); + if (!inters.isApprox(e1)) { + edge_on_plane.first += radius * edge_on_plane_dir; + edge_on_plane.second += radius * edge_on_plane_dir; + } + return AngleAndEdges(0.5 * double(PI), inters, std::make_pair(e1, e2), edge_on_plane, radius, inters.isApprox(e1)); + } const Vec3d e1e2 = e2 - e1; const double e1e2_len = e1e2.norm(); @@ -771,7 +800,8 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// - } else if (f1.get_type() == SurfaceFeatureType::Edge) { + } + else if (f1.get_type() == SurfaceFeatureType::Edge) { if (f2.get_type() == SurfaceFeatureType::Edge) { std::vector distances; @@ -898,21 +928,6 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& const Vec3d D = c1 - c0; if (!are_parallel(n0, n1)) { - auto orthonormal_basis = [](const Vec3d& v) { - std::array ret; - ret[2] = v.normalized(); - int index; - ret[2].maxCoeff(&index); - switch (index) - { - case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; } - case 1: { ret[0] = Vec3d(0.0, ret[2].z(), -ret[2].y()).normalized(); break; } - case 2: { ret[0] = Vec3d(-ret[2].z(), 0.0, ret[2].x()).normalized(); break; } - } - ret[1] = ret[2].cross(ret[0]).normalized(); - return ret; - }; - // Get parameters for constructing the degree-8 polynomial phi. const double one = 1.0; const double two = 2.0; From c57247b044928ed74318686d24a654bb26f61c84 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 15:44:01 +0100 Subject: [PATCH 11/99] Removed debug code --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 23b130d282..33d65ddc53 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -396,7 +396,6 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) else if (mouse_event.RightDown()) { // let the event pass through to allow panning/rotating the 3D scene if ((m_mode != EMode::CenterSelection && mouse_event.CmdDown()) || (m_mode == EMode::CenterSelection && m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID)) { - std::cout << "RightDown -> false\n"; return false; } From 3eaa4b014996b8c37efba17eebaa048ad0eb9df8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 18 Nov 2022 08:42:47 +0100 Subject: [PATCH 12/99] Gizmo measure - Draw background for dimensioning labels --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 33d65ddc53..6dfd5dbcec 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1068,8 +1068,17 @@ void GLGizmoMeasure::render_dimensioning() ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 1.0f, 1.0f }); m_imgui->begin(std::string("distance"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration); + ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); ImGui::AlignTextToFramePadding(); - m_imgui->text(curr_value_str + " " + units); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 pos = ImGui::GetCursorScreenPos(); + const std::string txt = curr_value_str + " " + units; + ImVec2 txt_size = ImGui::CalcTextSize(txt.c_str()); + const ImGuiStyle& style = ImGui::GetStyle(); + draw_list->AddRectFilled({ pos.x - style.FramePadding.x, pos.y + style.FramePadding.y }, { pos.x + txt_size.x + 2.0f * style.FramePadding.x , pos.y + txt_size.y + 2.0f * style.FramePadding.y }, + ImGuiWrapper::to_ImU32(ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f))); + ImGui::SetCursorScreenPos({ pos.x + style.FramePadding.x, pos.y }); + m_imgui->text(txt); ImGui::SameLine(); if (m_imgui->image_button(ImGui::SliderFloatEditBtnIcon, _L("Edit to scale"))) { m_editing_distance = true; @@ -1342,7 +1351,16 @@ void GLGizmoMeasure::render_dimensioning() ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); m_imgui->begin(_L("##angle"), ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); - m_imgui->text(format_double(Geometry::rad2deg(angle)) + "°"); + ImGui::AlignTextToFramePadding(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 pos = ImGui::GetCursorScreenPos(); + const std::string txt = format_double(Geometry::rad2deg(angle)) + "°"; + ImVec2 txt_size = ImGui::CalcTextSize(txt.c_str()); + const ImGuiStyle& style = ImGui::GetStyle(); + draw_list->AddRectFilled({ pos.x - style.FramePadding.x, pos.y + style.FramePadding.y }, { pos.x + txt_size.x + 2.0f * style.FramePadding.x , pos.y + txt_size.y + 2.0f * style.FramePadding.y }, + ImGuiWrapper::to_ImU32(ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f))); + ImGui::SetCursorScreenPos({ pos.x + style.FramePadding.x, pos.y }); + m_imgui->text(txt); m_imgui->end(); ImGui::PopStyleVar(); }; From 4435484a0a9aa254add6a7b2285910778efbd967 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 18 Nov 2022 10:53:42 +0100 Subject: [PATCH 13/99] Gizmo measure - Show diameter of selected circles into imgui dialog --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 6dfd5dbcec..36a8ab0474 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1786,10 +1786,23 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ImGui::Separator(); const ImGuiTableFlags flags = ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersH; if (ImGui::BeginTable("Selection", 2, flags)) { - add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 1:", ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR), m_selected_features.first.feature.has_value() ? - m_selected_features.first.source : _u8L("None"), ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR)); - add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 2:", ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR), m_selected_features.second.feature.has_value() ? - m_selected_features.second.source : _u8L("None"), ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR)); + auto format_item_text = [use_inches, &units](const SelectedFeatures::Item& item) { + std::string txt = item.feature.has_value() ? item.source : _u8L("None"); + if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) { + auto [center, radius, normal] = item.feature->get_circle(); + const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); + radius = (on_circle - center).norm(); + if (use_inches) + radius = ObjectManipulation::mm_to_in * radius; + txt += " (" + _u8L("Diameter:") + " " + format_double(2.0 * radius) + units + ")"; + } + return txt; + }; + + add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 1:", ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR), format_item_text(m_selected_features.first), + ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR)); + add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 2:", ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR), format_item_text(m_selected_features.second), + ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR)); ImGui::EndTable(); } From 83c0be60610aec8d763a4a7abeb1c501928203b0 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 18 Nov 2022 11:17:20 +0100 Subject: [PATCH 14/99] Removed commented out code --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 104 ----------------------- 1 file changed, 104 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 36a8ab0474..0b7a43c746 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1679,110 +1679,6 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit const bool use_inches = wxGetApp().app_config->get("use_inches") == "1"; const std::string units = use_inches ? " " + _u8L("in") : " " + _u8L("mm"); - //const Measure::SurfaceFeatureType feature_type = m_curr_feature.has_value() ? m_curr_feature->get_type() : Measure::SurfaceFeatureType::Undef; - //bool data_text_set = false; - //ImGui::Separator(); - //if (feature_type != Measure::SurfaceFeatureType::Undef) { - // if (m_mode == EMode::FeatureSelection) { - // m_imgui->text(surface_feature_type_as_string(feature_type)); - // data_text_set = true; - // } - // else if (m_mode == EMode::PointSelection) { - // if (m_hover_id != -1 && m_curr_point_on_feature_position.has_value()) { - // m_imgui->text(point_on_feature_type_as_string(feature_type, m_hover_id)); - // data_text_set = true; - // } - // } - // else if (m_mode == EMode::CenterSelection) { - // if (m_hover_id != -1 && m_curr_point_on_feature_position.has_value()) { - // m_imgui->text(center_on_feature_type_as_string(feature_type)); - // data_text_set = true; - // } - // } - //} - //if (!data_text_set) - // m_imgui->text(_u8L("No feature")); - - //const unsigned int max_data_row_count = 3; - //unsigned int data_row_count = 0; - //if (ImGui::BeginTable("Data", 2)) { - // if (m_mode == EMode::FeatureSelection) { - // switch (feature_type) - // { - // default: { break; } - // case Measure::SurfaceFeatureType::Point: - // { - // Vec3d position = m_volume_matrix * m_curr_feature->get_point(); - // if (use_inches) - // position = ObjectManipulation::mm_to_in * position; - // add_strings_row_to_table(*m_imgui, _u8L("Position"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(position), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 1; - // break; - // } - // case Measure::SurfaceFeatureType::Edge: - // { - // auto [from, to] = m_curr_feature->get_edge(); - // from = m_volume_matrix * from; - // to = m_volume_matrix * to; - // if (use_inches) { - // from = ObjectManipulation::mm_to_in * from; - // to = ObjectManipulation::mm_to_in * to; - // } - // add_strings_row_to_table(*m_imgui, _u8L("From"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(from), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("To"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(to), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("Length"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double((to - from).norm()) + units, ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 3; - // break; - // } - // case Measure::SurfaceFeatureType::Circle: - // { - // auto [center, radius, normal] = m_curr_feature->get_circle(); - // // generic point on circle, used to recalculate radius after transformation - // const Vec3d on_circle = m_volume_matrix * (center + radius * Measure::get_orthogonal(normal, true)); - // center = m_volume_matrix * center; - // normal = (m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal).normalized(); - // radius = (on_circle - center).norm(); - // if (use_inches) { - // center = ObjectManipulation::mm_to_in * center; - // radius = ObjectManipulation::mm_to_in * radius; - // } - // add_strings_row_to_table(*m_imgui, _u8L("Center"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(center), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("Radius"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(radius) + units, ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("Normal"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 3; - // break; - // } - // case Measure::SurfaceFeatureType::Plane: - // { - // auto [idx, normal, origin] = m_curr_feature->get_plane(); - // origin = m_volume_matrix * origin; - // normal = m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal; - // if (use_inches) - // origin = ObjectManipulation::mm_to_in * origin; - // add_strings_row_to_table(*m_imgui, _u8L("Origin"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(origin), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("Normal"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 2; - // break; - // } - // } - // } - // else { - // if (m_hover_id != -1 && m_curr_point_on_feature_position.has_value()) { - // Vec3d position = m_volume_matrix * *m_curr_point_on_feature_position; - // if (use_inches) - // position = ObjectManipulation::mm_to_in * position; - // add_strings_row_to_table(*m_imgui, _u8L("Position"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(position), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 1; - // } - // } - - // // add dummy rows to keep dialog size fixed - // for (unsigned int i = data_row_count; i < max_data_row_count; ++i) { - // add_strings_row_to_table(*m_imgui, " ", ImGuiWrapper::COL_ORANGE_LIGHT, " ", ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // } - // ImGui::EndTable(); - //} - ImGui::Separator(); const ImGuiTableFlags flags = ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersH; if (ImGui::BeginTable("Selection", 2, flags)) { From 3485db4f1b82495e34f33be1d3769466a1b6805b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 18 Nov 2022 14:53:19 +0100 Subject: [PATCH 15/99] Gizmo measure - Render dimensioning thicker main lines --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 72 +++++++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 0b7a43c746..ed83ae7ca9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1003,7 +1003,7 @@ void GLGizmoMeasure::render_dimensioning() if (shader == nullptr) return; - auto point_point = [this, shader](const Vec3d& v1, const Vec3d& v2, float distance) { + auto point_point = [this, &shader](const Vec3d& v1, const Vec3d& v2, float distance) { if ((v2 - v1).squaredNorm() < 0.000001 || distance < 0.001f) return; @@ -1033,6 +1033,25 @@ void GLGizmoMeasure::render_dimensioning() const Transform3d ss_to_ndc_matrix = TransformHelper::ndc_to_ss_matrix_inverse(viewport); +#if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_core_profile()) { + shader->stop_using(); + + shader = wxGetApp().get_shader("dashed_thick_lines"); + if (shader == nullptr) + return; + + shader->start_using(); + shader->set_uniform("projection_matrix", Transform3d::Identity()); + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 1.0f); + shader->set_uniform("gap_size", 0.0f); + } + else +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glLineWidth(2.0f)); + // stem shader->set_uniform("view_model_matrix", overlap ? ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss * Geometry::translation_transform(-2.0 * TRIANGLE_HEIGHT * Vec3d::UnitX()) * Geometry::scale_transform({ v12ss_len + 4.0 * TRIANGLE_HEIGHT, 1.0f, 1.0f }) : @@ -1040,6 +1059,20 @@ void GLGizmoMeasure::render_dimensioning() m_dimensioning.line.set_color(ColorRGBA::WHITE()); m_dimensioning.line.render(); +#if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_core_profile()) { + shader->stop_using(); + + shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + shader->start_using(); + } + else +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glLineWidth(1.0f)); + // arrow 1 shader->set_uniform("view_model_matrix", overlap ? ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss : @@ -1248,7 +1281,7 @@ void GLGizmoMeasure::render_dimensioning() } }; - auto arc_edge_edge = [this, shader](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2, double radius = 0.0) { + auto arc_edge_edge = [this, &shader](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2, double radius = 0.0) { assert(f1.get_type() == Measure::SurfaceFeatureType::Edge && f2.get_type() == Measure::SurfaceFeatureType::Edge); if (!m_measurement_result.angle.has_value()) return; @@ -1290,12 +1323,45 @@ void GLGizmoMeasure::render_dimensioning() m_dimensioning.arc.init_from(std::move(init_data)); } - // arc const Camera& camera = wxGetApp().plater()->get_camera(); +#if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_core_profile()) { + shader->stop_using(); + + shader = wxGetApp().get_shader("dashed_thick_lines"); + if (shader == nullptr) + return; + + shader->start_using(); + shader->set_uniform("projection_matrix", Transform3d::Identity()); + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 1.0f); + shader->set_uniform("gap_size", 0.0f); + } + else +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glLineWidth(2.0f)); + + // arc shader->set_uniform("projection_matrix", camera.get_projection_matrix()); shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::translation_transform(center)); m_dimensioning.arc.render(); +#if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_core_profile()) { + shader->stop_using(); + + shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + shader->start_using(); + } + else +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glLineWidth(1.0f)); + // arrows auto render_arrow = [this, shader, &camera, &normal, ¢er, &e1_unit, draw_radius, step, resolution](unsigned int endpoint_id) { const double angle = (endpoint_id == 1) ? 0.0 : step * double(resolution); From fdc9c73340060cea7d8335e1211836681e18cae0 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 08:37:58 +0100 Subject: [PATCH 16/99] Gizmo Measure - When CTRL+dragging to pan/rotate the scene, do not select the hovered feature, if any --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index ed83ae7ca9..179e8c5d2d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -254,6 +254,7 @@ GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filen bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) { m_mouse_pos = { double(mouse_event.GetX()), double(mouse_event.GetY()) }; + m_dragging = false; if (mouse_event.Moving()) { // only for sure @@ -261,6 +262,8 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) return false; } else if (mouse_event.Dragging()) { + m_dragging = true; + // Enable/Disable panning/rotating the 3D scene // Ctrl is pressed or the mouse is not hovering a selected volume bool unlock_dragging = mouse_event.CmdDown() || (m_hover_id == -1 && !m_parent.get_selection().contains_volume(m_parent.get_first_hover_volume_idx())); @@ -578,7 +581,9 @@ void GLGizmoMeasure::on_render() m_curr_point_on_feature_position.reset(); } else { - std::optional curr_feature = mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; + std::optional curr_feature = m_dragging ? m_curr_feature : + mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; + if (m_curr_feature != curr_feature || (curr_feature.has_value() && curr_feature->get_type() == Measure::SurfaceFeatureType::Circle && (m_curr_feature != curr_feature || m_last_inv_zoom != inv_zoom))) { m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); From 4660527dda6881c1dfb51b115a75f8cfddf17cbd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 09:13:28 +0100 Subject: [PATCH 17/99] Gizmo Measure - Use [Delete] key in place of Shift+Right mouse to restart selection --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 13 ++++++------- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 179e8c5d2d..153ffaf8df 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -401,12 +401,6 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) if ((m_mode != EMode::CenterSelection && mouse_event.CmdDown()) || (m_mode == EMode::CenterSelection && m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID)) { return false; } - - if (mouse_event.ShiftDown()) { - m_selected_features.reset(); - m_selection_raycasters.clear(); - m_parent.request_extra_frame(); - } } else if (mouse_event.Leaving()) m_mouse_left_down = false; @@ -477,6 +471,11 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po m_mode = control_down ? EMode::PointSelection : EMode::FeatureSelection; restore_scene_raycasters_state(); } + else if (action == SLAGizmoEventType::Delete) { + m_selected_features.reset(); + m_selection_raycasters.clear(); + m_parent.request_extra_frame(); + } return true; } @@ -1735,7 +1734,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit } if (m_selected_features.first.feature.has_value()) { - add_strings_row_to_table(*m_imgui, _u8L("Shift") + "+" + _u8L("Right mouse button"), ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Restart selection"), ImGui::GetStyleColorVec4(ImGuiCol_Text)); + add_strings_row_to_table(*m_imgui, _u8L("Delete"), ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Restart selection"), ImGui::GetStyleColorVec4(ImGuiCol_Text)); ++row_count; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 07b4baa350..a97dce346d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -552,7 +552,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt) case WXK_BACK: case WXK_DELETE: { - if ((m_current == SlaSupports || m_current == Hollow || m_current == Cut) && gizmo_event(SLAGizmoEventType::Delete)) + if ((m_current == SlaSupports || m_current == Hollow || m_current == Cut || m_current == Measure) && gizmo_event(SLAGizmoEventType::Delete)) processed = true; break; From 5cbe5c9d73e83f39469d62c8e1614898fb58e734 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 09:46:30 +0100 Subject: [PATCH 18/99] Gizmo Measure - Added [Restart selection] button to imgui dialog --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 153ffaf8df..ae1f90a258 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1772,13 +1772,13 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ImGui::EndTable(); } - //if (m_selected_features.first.feature.has_value()) { - // if (m_imgui->button(_u8L("Restart"))) { - // m_selected_features.reset(); - // m_selection_raycasters.clear(); - // m_imgui->set_requires_extra_frame(); - // } - //} + m_imgui->disabled_begin(!m_selected_features.first.feature.has_value()); + if (m_imgui->button(_u8L("Restart selection"))) { + m_selected_features.reset(); + m_selection_raycasters.clear(); + m_imgui->set_requires_extra_frame(); + } + m_imgui->disabled_end(); auto add_measure_row_to_table = [this](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color) { ImGui::TableNextRow(); From f0e8a22504da74e8ddc3867a0cf14b821a32d736 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 10:26:53 +0100 Subject: [PATCH 19/99] Gizmo Measure - Clicking on 1st selected let second selected to be promoted as first selected --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 27 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index ae1f90a258..1ec7cc5c1c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -354,6 +354,10 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) else { if (!m_selected_features.second.feature.has_value()) m_selected_features.first.reset(); + else { + m_selected_features.first = m_selected_features.second; + m_selected_features.second.reset(); + } } } else { @@ -850,7 +854,7 @@ void GLGizmoMeasure::on_render() }; auto hover_selection_color = [this]() { - return !m_selected_features.first.feature.has_value() ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; + return (!m_selected_features.first.feature.has_value() || *m_curr_feature == *m_selected_features.first.feature) ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; }; auto hovering_color = [this, hover_selection_color, &selection]() { @@ -1690,14 +1694,27 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit std::string text; ColorRGBA color; if (m_selected_features.second.feature.has_value()) { - if (m_selected_features.second.feature == m_curr_feature && m_mode == EMode::FeatureSelection) + if (m_selected_features.first.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { text = _u8L("Unselect feature"); - else if (m_hover_id == SELECTION_2_ID) + color = SELECTED_1ST_COLOR; + } + else if (m_selected_features.second.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { + text = _u8L("Unselect feature"); + color = SELECTED_2ND_COLOR; + } + else if (m_hover_id == SELECTION_1_ID) { text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); - else + color = SELECTED_1ST_COLOR; + } + else if (m_hover_id == SELECTION_2_ID) { + text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); + color = SELECTED_2ND_COLOR; + } + else { text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : (m_mode == EMode::CenterSelection) ? _u8L("Select center") : _u8L("Select feature"); - color = SELECTED_2ND_COLOR; + color = SELECTED_2ND_COLOR; + } } else { if (m_selected_features.first.feature.has_value()) { From 621a43c3a2b5eca5373206eee9798ee2bb33a7f7 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 11:20:14 +0100 Subject: [PATCH 20/99] Gizmo Measure - Handling of [ESC] key When two features are selected -> unselected second feature When one feature is selected -> unselect first feature When no feature is selected -> close gizmo --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 31 ++++++++++++++++++++++- src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 5 +++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 1ec7cc5c1c..d50ef9e269 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -480,6 +480,16 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po m_selection_raycasters.clear(); m_parent.request_extra_frame(); } + else if (action == SLAGizmoEventType::Escape) { + if (!m_selected_features.first.feature.has_value()) + return false; + else { + if (m_selected_features.second.feature.has_value()) + m_selected_features.second.feature.reset(); + else + m_selected_features.first.feature.reset(); + } + } return true; } @@ -1755,8 +1765,27 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ++row_count; } + if (m_selected_features.first.feature.has_value() || m_selected_features.second.feature.has_value()) { + add_row_to_table( + [this]() { + m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Esc")); + }, + [this]() { + m_imgui->text_colored(ImGui::GetStyleColorVec4(ImGuiCol_Text), _u8L("Unselect")); + ImGui::SameLine(); + const ImVec2 pos = ImGui::GetCursorScreenPos(); + const float rect_size = ImGui::GetTextLineHeight(); + const ColorRGBA color = m_selected_features.second.feature.has_value() ? SELECTED_2ND_COLOR : SELECTED_1ST_COLOR; + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + rect_size, pos.y + rect_size), ImGuiWrapper::to_ImU32(color)); + ImGui::Dummy(ImVec2(rect_size, rect_size)); + } + ); + + ++row_count; + } + // add dummy rows to keep dialog size fixed - for (unsigned int i = row_count; i < 4; ++i) { + for (unsigned int i = row_count; i < 5; ++i) { add_strings_row_to_table(*m_imgui, " ", ImGuiWrapper::COL_ORANGE_LIGHT, " ", ImGui::GetStyleColorVec4(ImGuiCol_Text)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 3878c6b25a..c1b605726c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -29,6 +29,7 @@ enum class SLAGizmoEventType : unsigned char { ShiftDown, ShiftUp, AltUp, + Escape, ApplyChanges, DiscardChanges, AutomaticGeneration, diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index a97dce346d..62ccce73e4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -524,7 +524,10 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt) case WXK_ESCAPE: { if (m_current != Undefined) { - if ((m_current != SlaSupports) || !gizmo_event(SLAGizmoEventType::DiscardChanges)) + if (m_current == Measure && gizmo_event(SLAGizmoEventType::Escape)) { + // do nothing + } + else if (m_current != SlaSupports || !gizmo_event(SLAGizmoEventType::DiscardChanges)) reset_all_states(); processed = true; From e6ea462ae63d6ae38e1cf174b32c2cfb6d1baaf5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 12:01:22 +0100 Subject: [PATCH 21/99] Gizmo Measure - Fixed point color and hint in dialog when adding a point on a selected feature --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index d50ef9e269..428ce5617e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -864,7 +864,9 @@ void GLGizmoMeasure::on_render() }; auto hover_selection_color = [this]() { - return (!m_selected_features.first.feature.has_value() || *m_curr_feature == *m_selected_features.first.feature) ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; + return ((m_mode == EMode::PointSelection && !m_selected_features.first.feature.has_value()) || + (m_mode != EMode::PointSelection && (!m_selected_features.first.feature.has_value() || *m_curr_feature == *m_selected_features.first.feature))) ? + SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; }; auto hovering_color = [this, hover_selection_color, &selection]() { @@ -1728,11 +1730,14 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit } else { if (m_selected_features.first.feature.has_value()) { - if (m_selected_features.first.feature == m_curr_feature) + if (m_selected_features.first.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { text = _u8L("Unselect feature"); - else if (m_hover_id == SELECTION_1_ID) + color = SELECTED_1ST_COLOR; + } + else if (m_hover_id == SELECTION_1_ID) { text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); - color = SELECTED_1ST_COLOR; + color = SELECTED_1ST_COLOR; + } } if (text.empty()) { text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : From 42e78720f98fc36bc9e5cb74bbc5582290bcf839 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 14:44:31 +0100 Subject: [PATCH 22/99] Fixed crash when opening Measure Gizmo after slicing in SLA mode --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 428ce5617e..2b6e1dcd3e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -965,7 +965,7 @@ void GLGizmoMeasure::update_if_needed() // continue; TriangleMesh volume_mesh = vol.volume->mesh(); - volume_mesh.transform(vol.instance->get_transformation().get_matrix() * vol.volume->get_transformation().get_matrix()); + volume_mesh.transform(vol.world_trafo); composite_mesh.merge(volume_mesh); } @@ -984,10 +984,17 @@ void GLGizmoMeasure::update_if_needed() volumes_cache.reserve(idxs.size()); for (unsigned int idx : idxs) { const GLVolume* v = selection.get_volume(idx); + const int volume_idx = v->volume_idx(); + if (volume_idx < 0) + continue; + const ModelObject* obj = selection.get_model()->objects[v->object_idx()]; const ModelInstance* inst = obj->instances[v->instance_idx()]; - const ModelVolume* vol = obj->volumes[v->volume_idx()]; - const VolumeCacheItem item = { obj, inst, vol, inst->get_matrix() * vol->get_matrix() }; + const ModelVolume* vol = obj->volumes[volume_idx]; + const VolumeCacheItem item = { + obj, inst, vol, + Geometry::translation_transform(selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) * inst->get_matrix() * vol->get_matrix() + }; volumes_cache.emplace_back(item); } From b75e403d147eef901d13b15a1cb64a9e5cd6482b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 22 Nov 2022 08:34:12 +0100 Subject: [PATCH 23/99] Gizmo measure - Fixed dimensioning after scaling a part of a multipart object --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 2b6e1dcd3e..1395847994 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1171,16 +1171,14 @@ void GLGizmoMeasure::render_dimensioning() Vec3d new_pivot; Transform3d scale_matrix; - TrafoData(double ratio, const Vec3d& pivot) { + TrafoData(double ratio, const Vec3d& old_pivot, const Vec3d& new_pivot) { this->ratio = ratio; this->scale_matrix = Geometry::scale_transform(ratio); - this->old_pivot = pivot; - this->new_pivot = { pivot.x(), pivot.y(), (this->scale_matrix * pivot).z() }; + this->old_pivot = old_pivot; + this->new_pivot = new_pivot; } - Vec3d transform(const Vec3d& point) const { - return this->scale_matrix * (point - this->old_pivot) + this->new_pivot; - } + Vec3d transform(const Vec3d& point) const { return this->scale_matrix * (point - this->old_pivot) + this->new_pivot; } }; auto scale_feature = [](Measure::SurfaceFeature& feature, const TrafoData& trafo_data) { @@ -1215,22 +1213,26 @@ void GLGizmoMeasure::render_dimensioning() } }; - const TrafoData trafo_data(ratio, m_parent.get_selection().get_bounding_box().center()); - scale_feature(*m_selected_features.first.feature, trafo_data); - scale_feature(*m_selected_features.second.feature, trafo_data); - + // apply scale TransformationType type; type.set_world(); type.set_relative(); type.set_joint(); - // apply scale + // scale selection Selection& selection = m_parent.get_selection(); + const Vec3d old_center = selection.get_bounding_box().center(); selection.setup_cache(); selection.scale(ratio * Vec3d::Ones(), type); wxGetApp().plater()->canvas3D()->do_scale(""); // avoid storing another snapshot wxGetApp().obj_manipul()->set_dirty(); + // scale dimensioning + const Vec3d new_center = selection.get_bounding_box().center(); + const TrafoData trafo_data(ratio, old_center, new_center); + scale_feature(*m_selected_features.first.feature, trafo_data); + scale_feature(*m_selected_features.second.feature, trafo_data); + // update measure on next call to data_changed() m_pending_scale = true; }; From 9bdaf0bae2ba857204e3ed95c7683ab9baa4df8b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 22 Nov 2022 12:36:51 +0100 Subject: [PATCH 24/99] Gizmo measure - Fixed incorrect point on feature detection --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 1395847994..1e4ba61c70 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -666,7 +666,7 @@ void GLGizmoMeasure::on_render() return trafo * p.cast(); } } - return Vec3d::Zero(); + return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); }; if (m_curr_feature.has_value()) { @@ -683,8 +683,11 @@ void GLGizmoMeasure::on_render() const std::optional extra = m_curr_feature->get_extra_point(); if (extra.has_value() && m_hover_id == POINT_ID) m_curr_point_on_feature_position = *extra; - else - m_curr_point_on_feature_position = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); + else { + const Vec3d pos = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); + if (!pos.isApprox(Vec3d(DBL_MAX, DBL_MAX, DBL_MAX))) + m_curr_point_on_feature_position = pos; + } break; } case Measure::SurfaceFeatureType::Plane: @@ -715,6 +718,7 @@ void GLGizmoMeasure::on_render() } } else { + m_curr_point_on_feature_position.reset(); if (m_curr_feature.has_value() && m_curr_feature->get_type() == Measure::SurfaceFeatureType::Circle) { if (update_circle()) { m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); From d1146ae67a74ef441efbeac0bc55c951f70d028c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 22 Nov 2022 13:13:25 +0100 Subject: [PATCH 25/99] Gizmo measure - Fixed calculation of angle edge-plane --- src/libslic3r/Measure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 535b898cf4..17689063c3 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -32,7 +32,7 @@ static std::array orthonormal_basis(const Vec3d& v) std::array ret; ret[2] = v.normalized(); int index; - ret[2].maxCoeff(&index); + ret[2].cwiseAbs().maxCoeff(&index); switch (index) { case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; } From 456837d54159765592a749176fb27c5ab943af19 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 22 Nov 2022 14:40:35 +0100 Subject: [PATCH 26/99] Follow-up of fdc9c73340060cea7d8335e1211836681e18cae0 - Alternate implementation of 'When panning/rotating the scene, do not select the hovered feature, if any' --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 1e4ba61c70..0255bd1e3b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -254,7 +254,6 @@ GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filen bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) { m_mouse_pos = { double(mouse_event.GetX()), double(mouse_event.GetY()) }; - m_dragging = false; if (mouse_event.Moving()) { // only for sure @@ -262,8 +261,6 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) return false; } else if (mouse_event.Dragging()) { - m_dragging = true; - // Enable/Disable panning/rotating the 3D scene // Ctrl is pressed or the mouse is not hovering a selected volume bool unlock_dragging = mouse_event.CmdDown() || (m_hover_id == -1 && !m_parent.get_selection().contains_volume(m_parent.get_first_hover_volume_idx())); @@ -594,7 +591,7 @@ void GLGizmoMeasure::on_render() m_curr_point_on_feature_position.reset(); } else { - std::optional curr_feature = m_dragging ? m_curr_feature : + std::optional curr_feature = wxGetMouseState().LeftIsDown() ? m_curr_feature : mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; if (m_curr_feature != curr_feature || From d437d1bebf83df16c88340b8ffeb5d8d3f59dd64 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Nov 2022 08:24:08 +0100 Subject: [PATCH 27/99] Gizmo measure - Fixed color of hovered features when part of the object is outside the printbed --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 0255bd1e3b..55f1027529 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -752,7 +752,7 @@ void GLGizmoMeasure::on_render() }; auto set_emission_uniform = [this, shader](const ColorRGBA& color, bool hover) { - shader->set_uniform("emission_factor", (color == m_parent.get_selection().get_first_volume()->render_color) ? 0.0f : + shader->set_uniform("emission_factor", (color == GLVolume::SELECTED_COLOR) ? 0.0f : hover ? 0.5f : 0.25f); }; @@ -871,7 +871,7 @@ void GLGizmoMeasure::on_render() }; auto hovering_color = [this, hover_selection_color, &selection]() { - return (m_mode == EMode::PointSelection) ? selection.get_first_volume()->render_color : hover_selection_color(); + return (m_mode == EMode::PointSelection) ? GLVolume::SELECTED_COLOR : hover_selection_color(); }; if (m_curr_feature.has_value()) { From 2a944d4cdeb616dfa5def543bf2fd19a88709a90 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Nov 2022 09:10:56 +0100 Subject: [PATCH 28/99] Fixed warnings --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 55f1027529..6489340b89 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -751,7 +751,7 @@ void GLGizmoMeasure::on_render() shader->set_uniform("view_normal_matrix", view_normal_matrix); }; - auto set_emission_uniform = [this, shader](const ColorRGBA& color, bool hover) { + auto set_emission_uniform = [shader](const ColorRGBA& color, bool hover) { shader->set_uniform("emission_factor", (color == GLVolume::SELECTED_COLOR) ? 0.0f : hover ? 0.5f : 0.25f); }; @@ -870,7 +870,7 @@ void GLGizmoMeasure::on_render() SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; }; - auto hovering_color = [this, hover_selection_color, &selection]() { + auto hovering_color = [this, hover_selection_color]() { return (m_mode == EMode::PointSelection) ? GLVolume::SELECTED_COLOR : hover_selection_color(); }; From cc13e8a44f3cc4711e9e0a03af45dd5cdb6df981 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Nov 2022 12:03:36 +0100 Subject: [PATCH 29/99] Gizmo measure - Hide SLA supports and pad when opening the gizmo --- src/slic3r/GUI/GLCanvas3D.cpp | 19 +++++++++++++++++-- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 5 +++++ src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e631643aec..b64a982b8f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1346,11 +1346,26 @@ void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObje m_render_sla_auxiliaries = visible; +#if ENABLE_RAYCAST_PICKING + std::vector>* raycasters = get_raycasters_for_picking(SceneRaycaster::EType::Volume); +#endif // ENABLE_RAYCAST_PICKING + for (GLVolume* vol : m_volumes.volumes) { +#if ENABLE_RAYCAST_PICKING if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) - && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) - && vol->composite_id.volume_id < 0) + && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) + && vol->composite_id.volume_id < 0) { vol->is_active = visible; + auto it = std::find_if(raycasters->begin(), raycasters->end(), [vol](std::shared_ptr item) { return item->get_raycaster() == vol->mesh_raycaster.get(); }); + if (it != raycasters->end()) + (*it)->set_active(vol->is_active); + } +#else + if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) + && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) + && vol->composite_id.volume_id < 0) + vol->is_active = visible; +#endif // ENABLE_RAYCAST_PICKING } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 1ce118d71d..51ea56c821 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -900,6 +900,11 @@ RENDER_AGAIN: bool show_sups = m_c->instances_hider()->are_supports_shown(); if (m_imgui->checkbox(m_desc["show_supports"], show_sups)) { m_c->instances_hider()->show_supports(show_sups); +#if ENABLE_RAYCAST_PICKING + if (show_sups) + // ensure supports and pad are disabled from picking even when they are visible + set_sla_auxiliary_volumes_picking_state(false); +#endif // ENABLE_RAYCAST_PICKING force_refresh = true; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 6489340b89..38dd4686e4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -411,6 +411,8 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) void GLGizmoMeasure::data_changed() { + m_parent.toggle_sla_auxiliaries_visibility(false, nullptr, -1); + update_if_needed(); m_last_inv_zoom = 0.0f; @@ -500,6 +502,7 @@ bool GLGizmoMeasure::on_init() void GLGizmoMeasure::on_set_state() { if (m_state == Off) { + m_parent.toggle_sla_auxiliaries_visibility(true, nullptr, -1); m_ctrl_kar_filter.reset_count(); m_shift_kar_filter.reset_count(); m_curr_feature.reset(); From 3c1ec473a741939baee83d475040acfdaa71d41d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Nov 2022 12:37:54 +0100 Subject: [PATCH 30/99] Gizmo measure - Undo/Redo related fix --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 9699d73cc8..1672e8b74e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -159,6 +159,11 @@ public: bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); + bool wants_enter_leave_snapshots() const override { return true; } + std::string get_gizmo_entering_text() const override { return _u8L("Entering Measure gizmo"); } + std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Measure gizmo"); } + std::string get_action_snapshot_name() override { return _u8L("Measure gizmo editing"); } + protected: bool on_init() override; std::string on_get_name() const override; From 9952003f61c9a9b12613b40846f8cd2af014a523 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 22 Nov 2022 09:49:10 +0100 Subject: [PATCH 31/99] Measurement: Fixed and refactored circle detection: - first/last segment of a circular segment was sometimes separated - circles were sometimes shown where they shouldn't be --- src/libslic3r/Measure.cpp | 236 +++++++++++++++++++------------------- 1 file changed, 120 insertions(+), 116 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 17689063c3..e80ff50195 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -12,17 +12,17 @@ namespace Measure { constexpr double feature_hover_limit = 0.5; // how close to a feature the mouse must be to highlight it -static std::pair get_center_and_radius(const std::vector& border, int start_idx, int end_idx, const Transform3d& trafo) +static std::pair get_center_and_radius(const std::vector& points, const Transform3d& trafo) { - Vec2ds pts; + Vec2ds out; double z = 0.; - for (int i=start_idx; i<=end_idx; ++i) { - Vec3d pt_transformed = trafo * border[i]; + for (const Vec3d pt : points) { + Vec3d pt_transformed = trafo * pt; z = pt_transformed.z(); - pts.emplace_back(pt_transformed.x(), pt_transformed.y()); + out.emplace_back(pt_transformed.x(), pt_transformed.y()); } - auto circle = Geometry::circle_ransac(pts, 20); // FIXME: iterations? + auto circle = Geometry::circle_ransac(out, 20); // FIXME: iterations? return std::make_pair(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius); } @@ -214,6 +214,7 @@ void MeasuringImpl::update_planes() m_planes[plane_id].borders.pop_back(); else { assert(last_border.front() == last_border.back()); + last_border.pop_back(); } } } @@ -231,6 +232,9 @@ void MeasuringImpl::update_planes() void MeasuringImpl::extract_features() { + auto are_angles_same = [](double a, double b) { return Slic3r::is_approx(a,b); }; + auto are_lengths_same = [](double a, double b) { return Slic3r::is_approx(a,b); }; + std::vector angles; std::vector lengths; @@ -244,152 +248,152 @@ void MeasuringImpl::extract_features() q.setFromTwoVectors(plane.normal, Vec3d::UnitZ()); Transform3d trafo = Transform3d::Identity(); trafo.rotate(q); - + for (const std::vector& border : plane.borders) { if (border.size() <= 1) continue; - assert(border.front() == border.back()); - int start_idx = -1; - std::vector edges; + // Given an idx into border, return the index that is idx+offset position, + // while taking into account the need for warp-around and the fact that + // the first and last point are the same. + auto offset_to_index = [border_size = int(border.size())](int idx, int offset) -> int { + assert(std::abs(offset) < border_size); + int out = idx+offset; + if (out >= border_size) + out = out - border_size; + else if (out < 0) + out = border_size + out; + + return out; + }; // First calculate angles at all the vertices. angles.clear(); lengths.clear(); - for (int i=0; i M_PI) angle = 2*M_PI - angle; angles.push_back(angle); lengths.push_back(v2.norm()); + if (first_different_angle_idx == 0 && angles.size() > 1) { + if (! are_angles_same(angles.back(), angles[angles.size()-2])) + first_different_angle_idx = angles.size()-1; + } } assert(border.size() == angles.size()); assert(border.size() == lengths.size()); - // First go around the border and pick what might be circular segments. // Save pair of indices to where such potential segments start and end. // Also remember the length of these segments. + int start_idx = -1; bool circle = false; + bool first_iter = true; std::vector circles; + std::vector edges; std::vector> circles_idxs; - std::vector circles_lengths; - for (int i=1; i<(int)angles.size(); ++i) { - if (Slic3r::is_approx(lengths[i], lengths[i-1]) - && Slic3r::is_approx(angles[i], angles[i-1]) - && i != (int)angles.size()-1 ) { + //std::vector circles_lengths; + std::vector single_circle; // could be in loop-scope, but reallocations + double single_circle_length = 0.; + int first_pt_idx = offset_to_index(first_different_angle_idx, 1); + int i = first_pt_idx; + while (i != first_pt_idx || first_iter) { + if (are_angles_same(angles[i], angles[offset_to_index(i,-1)]) + && i != offset_to_index(first_pt_idx, -1) // not the last point + && i != start_idx ) { // circle if (! circle) { circle = true; - start_idx = std::max(0, i-2); + single_circle.clear(); + single_circle_length = 0.; + start_idx = offset_to_index(i, -2); + single_circle = { border[start_idx], border[offset_to_index(start_idx,1)] }; + single_circle_length += lengths[offset_to_index(i, -1)]; } + single_circle.emplace_back(border[i]); + single_circle_length += lengths[i]; } else { - if (circle) { - const auto& [center, radius] = get_center_and_radius(border, start_idx, i, trafo); - // Add the circle and remember indices into borders. - circles_idxs.emplace_back(start_idx, i); - circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius)); - circles_lengths.emplace_back(std::accumulate(lengths.begin() + start_idx + 1, lengths.begin() + i + 1, 0.)); - circle = false; - } - } - } + if (circle && single_circle.size() >= 5) { // Less than 5 vertices? Not a circle. + single_circle.emplace_back(border[i]); + single_circle_length += lengths[i]; - // At this point we might need to merge the first and last segment, if the starting - // point happened to be inside the segment. The discrimination of too small segments - // will follow, so we need a complete picture before that. - if (circles_idxs.size() > 1 - && circles_idxs.back().second == (int)angles.size()-1 - && circles_idxs.front().first == 0) { - // Possibly the same circle. Check that the angle and length criterion holds along the combined segment. - bool same = true; - double last_len = -1.; - double last_angle = 0.; - for (int i=circles_idxs.back().first + 1; i != circles_idxs.front().second; ++i) { - if (i == (int)angles.size()) - i = 1; - if (last_len == -1.) { - last_len = lengths[i]; - last_angle = angles[i]; - } else { - if (! Slic3r::is_approx(lengths[i], last_len) || ! Slic3r::is_approx(angles[i], last_angle)) { - same = false; - break; + bool accept_circle = true; + { + // Check that lengths of internal (!!!) edges match. + int j = offset_to_index(start_idx, 3); + while (j != i) { + if (! are_lengths_same(lengths[offset_to_index(j,-1)], lengths[j])) { + accept_circle = false; + break; + } + j = offset_to_index(j, 1); + } + } + + if (accept_circle) { + const auto& [center, radius] = get_center_and_radius(single_circle, trafo); + + // Check that the fit went well. The tolerance is high, only to + // reject complete failures. + for (const Vec3d& pt : single_circle) { + if (std::abs((pt - center).norm() - radius) > 0.5) { + accept_circle = false; + break; + } + } + + // If the segment subtends less than 90 degrees, throw it away. + accept_circle &= single_circle_length / radius > 0.9*M_PI/2.; + + // If this is all-around and 5 to 8 vertices, consider it a polygon. + bool is_polygon = start_idx == i && single_circle.size() <= 9 && single_circle.size() >= 6; + + if (accept_circle) { + // Add the circle and remember indices into borders. + circles_idxs.emplace_back(start_idx, i); + if (is_polygon) { + for (int j=0; j<=i; ++j) // No wrap-around handling needed here. + edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, + border[j==0 ? border.size()-1 : j-1], border[j], + std::make_optional(center))); + } + else + circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius)); + } } } + circle = false; } - if (same) { - // This seems to really be the same circle. Better apply ransac again. The parts can be small and inexact. - std::vector points(border.begin() + circles_idxs.back().first, border.end()); - points.insert(points.end(), border.begin(), border.begin() + circles_idxs.front().second+1); - auto [c, radius] = get_center_and_radius(points, 0, points.size()-1, trafo); - - // Now replace the first circle with the combined one, remove the last circle. - // First index of the first circle is saved negative - we are going to pick edges - // from the border later, we will need to know where the merged in segment was. - // The sign simplifies the algorithm that picks the remaining edges - see below. - circles.front() = SurfaceFeature(SurfaceFeatureType::Circle, c, plane.normal, std::nullopt, radius); - circles_idxs.front().first = - circles_idxs.back().first; - circles_lengths.front() += circles_lengths.back(); - circles.pop_back(); - circles_idxs.pop_back(); - circles_lengths.pop_back(); - } - } - - // Now throw away all circles that subtend less than 90 deg. - assert(circles.size() == circles_lengths.size()); - for (int i=0; i(circles[i].get_circle()); - if (circles_lengths[i] / r < 0.9*M_PI/2.) { - circles_lengths.erase(circles_lengths.begin() + i); - circles.erase(circles.begin() + i); - circles_idxs.erase(circles_idxs.begin() + i); - --i; - } + // Take care of the wrap around. + first_iter = false; + i = offset_to_index(i, 1); } - circles_lengths.clear(); // no longer needed, make it obvious - - // Anything under 5 vertices shall not be considered a circle. - assert(circles_idxs.size() == circles.size()); - for (int i=int(circles_idxs.size())-1; i>=0; --i) { - const auto& [start, end] = circles_idxs[i]; - int N = start >= 0 - ? end - start + (start == 0 && end == (int)border.size()-1 ? 0 : 1) // last point is the same as first - : end + (border.size() + start); - if (N < 5) { - circles.erase(circles.begin() + i); - circles_idxs.erase(circles_idxs.begin() + i); - } else if (N <= 8 && start == 0 && end == (int)border.size()-1) { - // This is a regular 5-8 polygon. Add the edges as edges with a special - // point and remove the circle. Leave the indices in circles_idxs, so - // the edges are not picked up again later. - const Vec3d center = std::get<0>(circles[i].get_circle()); - for (int j=1; j<=end; ++j) - edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, - border[j - 1], border[j], std::make_optional(center))); - circles.erase(circles.begin() + i); - } - } - // We have the circles. Now go around again and pick edges, while jumping over circles. - // If the first index of the first circle is negative, it means that it was merged - // with a segment that was originally at the back and is no longer there. Ressurect - // its pair of indices so that edges are not picked again. - if (! circles_idxs.empty() && circles_idxs.front().first < 0) - circles_idxs.emplace_back(-circles_idxs.front().first, int(border.size())); - int cidx = 0; // index of next circle to jump over - for (int i=1; i (int)circles_idxs[cidx].first) - i = circles_idxs[cidx++].second; - else - edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[i - 1], border[i])); + if (circles_idxs.empty()) { + // Just add all edges. + for (int i=1; i Date: Fri, 25 Nov 2022 13:45:23 +0100 Subject: [PATCH 32/99] Measurement: prevent ending up in an infinite loop with broken models --- src/libslic3r/Measure.cpp | 16 ++++++++++++++-- src/libslic3r/SurfaceMesh.hpp | 9 +++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index e80ff50195..5b9a75c045 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -187,10 +187,16 @@ void MeasuringImpl::update_planes() he = sm.next_around_target(he); if (he.is_invalid()) goto PLANE_FAILURE; + + // For broken meshes, the iteration might never get back to he_orig. + // Remember all halfedges we saw to break out of such infinite loops. + boost::container::small_vector he_seen; + while ( (int)m_face_to_plane[sm.face(he)] == plane_id && he != he_orig) { + he_seen.emplace_back(he); he = sm.next_around_target(he); - if (he.is_invalid()) - goto PLANE_FAILURE; + if (he.is_invalid() || std::find(he_seen.begin(), he_seen.end(), he) != he_seen.end()) + goto PLANE_FAILURE; } he = sm.opposite(he); if (he.is_invalid()) @@ -208,6 +214,12 @@ void MeasuringImpl::update_planes() visited[face_it - facets.begin()][he.side()] = true; last_border.emplace_back(sm.point(sm.source(he)).cast()); + + // In case of broken meshes, this loop might be infinite. Break + // out in case it is clearly going bad. + if (last_border.size() > 3*facets.size()) + goto PLANE_FAILURE; + } while (he != he_start); if (last_border.size() == 1) diff --git a/src/libslic3r/SurfaceMesh.hpp b/src/libslic3r/SurfaceMesh.hpp index 9e547eec49..93eb9fdaa6 100644 --- a/src/libslic3r/SurfaceMesh.hpp +++ b/src/libslic3r/SurfaceMesh.hpp @@ -4,6 +4,8 @@ #include #include +#include "boost/container/small_vector.hpp" + namespace Slic3r { class TriangleMesh; @@ -115,11 +117,18 @@ public: size_t degree(Vertex_index v) const { + // In case the mesh is broken badly, the loop might end up to be infinite, + // never getting back to the first halfedge. Remember list of all half-edges + // and trip if any is encountered for the second time. Halfedge_index h_first = halfedge(v); + boost::container::small_vector he_visited; Halfedge_index h = next_around_target(h_first); size_t degree = 2; while (! h.is_invalid() && h != h_first) { + he_visited.emplace_back(h); h = next_around_target(h); + if (std::find(he_visited.begin(), he_visited.end(), h) == he_visited.end()) + return 0; ++degree; } return h.is_invalid() ? 0 : degree - 1; From 5a3f36da0106a03ded52a066dc45507bae763b4b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 29 Nov 2022 11:13:09 +0100 Subject: [PATCH 33/99] Tech ENABLE_RAYCAST_PICKING_DEBUG - Extended data shown into debug imgui dialog --- src/slic3r/GUI/GLCanvas3D.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b64a982b8f..0261501d50 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5508,12 +5508,17 @@ void GLCanvas3D::_picking_pass() default: { break; } } - auto add_strings_row_to_table = [&imgui](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color) { + auto add_strings_row_to_table = [&imgui](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color, + const std::string& col_3 = "", const ImVec4& col_3_color = ImGui::GetStyleColorVec4(ImGuiCol_Text)) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); imgui.text_colored(col_1_color, col_1.c_str()); ImGui::TableSetColumnIndex(1); imgui.text_colored(col_2_color, col_2.c_str()); + if (!col_3.empty()) { + ImGui::TableSetColumnIndex(2); + imgui.text_colored(col_3_color, col_3.c_str()); + } }; char buf[1024]; @@ -5542,6 +5547,21 @@ void GLCanvas3D::_picking_pass() add_strings_row_to_table("Gizmo elements", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text)); ImGui::EndTable(); } + + std::vector>* gizmo_raycasters = m_scene_raycaster.get_raycasters(SceneRaycaster::EType::Gizmo); + if (gizmo_raycasters != nullptr && !gizmo_raycasters->empty()) { + ImGui::Separator(); + imgui.text("Gizmo raycasters IDs:"); + if (ImGui::BeginTable("GizmoRaycasters", 3)) { + for (size_t i = 0; i < gizmo_raycasters->size(); ++i) { + add_strings_row_to_table(std::to_string(i), ImGuiWrapper::COL_ORANGE_LIGHT, + std::to_string(SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, (*gizmo_raycasters)[i]->get_id())), ImGui::GetStyleColorVec4(ImGuiCol_Text), + to_string(Geometry::Transformation((*gizmo_raycasters)[i]->get_transform()).get_offset()), ImGui::GetStyleColorVec4(ImGuiCol_Text)); + } + ImGui::EndTable(); + } + } + imgui.end(); #endif // ENABLE_RAYCAST_PICKING_DEBUG } From 9323e347f0d19382e177f7e0b7fa048154b7c18a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 29 Nov 2022 12:59:05 +0100 Subject: [PATCH 34/99] ObjectList: Delete last volume from the object even if this volume is text --- src/slic3r/GUI/ObjectDataViewModel.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index cfc78f9f80..fe57d7d5a4 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -772,11 +772,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) // get index of the last VolumeItem in CildrenList size_t vol_idx = GetItemIndexForFirstVolume(node_parent); - ObjectDataViewModelNode *last_child_node = node_parent->GetNthChild(vol_idx); - // if last volume is text then don't delete it - if (last_child_node->is_text_volume()) - return parent; // delete this last volume DeleteSettings(wxDataViewItem(last_child_node)); From 9fe4595ae71765902a827575a4bcf361d0ee1f79 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 29 Nov 2022 16:21:45 +0100 Subject: [PATCH 35/99] CutGizmo: Cut plane wasn't respect to the depth + ShapesGallery: added "universal wall mount hole" --- resources/shapes/universal wall mount hole.png | Bin 0 -> 6573 bytes resources/shapes/universal wall mount hole.stl | Bin 0 -> 34584 bytes src/slic3r/GUI/GLCanvas3D.cpp | 4 +--- 3 files changed, 1 insertion(+), 3 deletions(-) create mode 100644 resources/shapes/universal wall mount hole.png create mode 100644 resources/shapes/universal wall mount hole.stl diff --git a/resources/shapes/universal wall mount hole.png b/resources/shapes/universal wall mount hole.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf7b9957605122fe1ad1dd953fce88daea2c72a GIT binary patch literal 6573 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 Q{QMHb*aVgxGcJVqU-Y}V(EtDd literal 0 HcmV?d00001 diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 11d1bb80c3..991bbead28 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1376,13 +1376,11 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject } else { const GLGizmosManager& gm = get_gizmos_manager(); auto gizmo_type = gm.get_current_type(); - if ( (gizmo_type == GLGizmosManager::FdmSupports + if ( (gizmo_type == GLGizmosManager::FdmSupports || gizmo_type == GLGizmosManager::Seam || gizmo_type == GLGizmosManager::Cut) && !vol->is_modifier) { vol->force_neutral_color = true; - if (gizmo_type == GLGizmosManager::Cut) - vol->color.a(0.95f); } else if (gizmo_type == GLGizmosManager::MmuSegmentation) vol->is_active = false; From 2a82f1d39689e5fffbe1d1dc3fee085489d4733e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 11:58:02 +0100 Subject: [PATCH 36/99] Gizmo measure - Modified circle and edge with extra point selection --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 510 ++++++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 18 +- 2 files changed, 320 insertions(+), 208 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 38dd4686e4..eb1a7162eb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -20,15 +20,16 @@ namespace Slic3r { namespace GUI { -static const Slic3r::ColorRGBA SELECTED_1ST_COLOR = { 0.25f, 0.75f, 0.75f, 1.0f }; -static const Slic3r::ColorRGBA SELECTED_2ND_COLOR = { 0.75f, 0.25f, 0.75f, 1.0f }; +static const Slic3r::ColorRGBA SELECTED_1ST_COLOR = { 0.25f, 0.75f, 0.75f, 1.0f }; +static const Slic3r::ColorRGBA SELECTED_2ND_COLOR = { 0.75f, 0.25f, 0.75f, 1.0f }; +static const Slic3r::ColorRGBA NEUTRAL_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f }; static const int POINT_ID = 100; static const int EDGE_ID = 200; static const int CIRCLE_ID = 300; static const int PLANE_ID = 400; -static const int SELECTION_1_ID = 501; -static const int SELECTION_2_ID = 502; +static const int SEL_SPHERE_1_ID = 501; +static const int SEL_SPHERE_2_ID = 502; static const float TRIANGLE_BASE = 10.0f; static const float TRIANGLE_HEIGHT = TRIANGLE_BASE * 1.618033f; @@ -164,6 +165,41 @@ static GLModel::Geometry init_torus_data(unsigned int primary_resolution, unsign return data; } +static bool is_feature_with_center(const Measure::SurfaceFeature& feature) +{ + const Measure::SurfaceFeatureType type = feature.get_type(); + return (type == Measure::SurfaceFeatureType::Circle || (type == Measure::SurfaceFeatureType::Edge && feature.get_extra_point().has_value())); +} + +static Vec3d get_feature_offset(const Measure::SurfaceFeature& feature) +{ + Vec3d ret; + switch (feature.get_type()) + { + case Measure::SurfaceFeatureType::Circle: + { + const auto [center, radius, normal] = feature.get_circle(); + ret = center; + break; + } + case Measure::SurfaceFeatureType::Edge: + { + std::optional p = feature.get_extra_point(); + assert(p.has_value()); + ret = *p; + break; + } + case Measure::SurfaceFeatureType::Point: + { + ret = feature.get_point(); + break; + } + default: { assert(false); } + } + + return ret; +} + class TransformHelper { struct Cache @@ -265,109 +301,125 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) // Ctrl is pressed or the mouse is not hovering a selected volume bool unlock_dragging = mouse_event.CmdDown() || (m_hover_id == -1 && !m_parent.get_selection().contains_volume(m_parent.get_first_hover_volume_idx())); // mode is not center selection or mouse is not hovering a center - unlock_dragging &= !mouse_event.ShiftDown() || (m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID && m_hover_id != POINT_ID); + unlock_dragging &= !mouse_event.ShiftDown() || (m_hover_id != SEL_SPHERE_1_ID && m_hover_id != SEL_SPHERE_2_ID && m_hover_id != POINT_ID); return !unlock_dragging; } else if (mouse_event.LeftDown()) { // let the event pass through to allow panning/rotating the 3D scene - if ((m_mode != EMode::CenterSelection && mouse_event.CmdDown()) || - (m_mode == EMode::CenterSelection && m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID && m_hover_id != POINT_ID)) { + if (mouse_event.CmdDown()) return false; - } if (m_hover_id != -1) { SelectedFeatures selected_features_old = m_selected_features; m_mouse_left_down = true; - auto item_from_feature = [this]() { + auto detect_current_item = [this]() { SelectedFeatures::Item item; - if (m_hover_id == SELECTION_1_ID && m_selected_features.first.feature.has_value()) - item = m_selected_features.first; - else if (m_hover_id == SELECTION_2_ID && m_selected_features.second.feature.has_value()) - item = m_selected_features.second; + if (m_hover_id == SEL_SPHERE_1_ID) { + if (m_selected_features.first.is_center) + // mouse is hovering over a selected center + item = { true, m_selected_features.first.source, { Measure::SurfaceFeature(get_feature_offset(*m_selected_features.first.source)) } }; + else if (is_feature_with_center(*m_selected_features.first.feature)) + // mouse is hovering over a unselected center + item = { true, m_selected_features.first.feature, { Measure::SurfaceFeature(get_feature_offset(*m_selected_features.first.feature)) } }; + else + // mouse is hovering over a point + item = m_selected_features.first; + } + else if (m_hover_id == SEL_SPHERE_2_ID) { + if (m_selected_features.second.is_center) + // mouse is hovering over a selected center + item = { true, m_selected_features.second.source, { Measure::SurfaceFeature(get_feature_offset(*m_selected_features.second.source)) } }; + else if (is_feature_with_center(*m_selected_features.second.feature)) + // mouse is hovering over a center + item = { true, m_selected_features.second.feature, { Measure::SurfaceFeature(get_feature_offset(*m_selected_features.second.feature)) } }; + else + // mouse is hovering over a point + item = m_selected_features.second; + } else { switch (m_mode) { - case EMode::FeatureSelection: - { - item = { surface_feature_type_as_string(m_curr_feature->get_type()), m_curr_feature }; - break; - } - case EMode::PointSelection: - { - item = { point_on_feature_type_as_string(m_curr_feature->get_type(), m_hover_id), Measure::SurfaceFeature(*m_curr_point_on_feature_position) }; - break; - } - case EMode::CenterSelection: - { - Vec3d position; - switch (m_curr_feature->get_type()) - { - case Measure::SurfaceFeatureType::Circle: - { - position = std::get<0>(m_curr_feature->get_circle()); - break; - } - case Measure::SurfaceFeatureType::Edge: - { - assert(m_curr_feature->get_extra_point().has_value()); - position = *m_curr_feature->get_extra_point(); - break; - } - default: { assert(false); break; } - } - - item = { center_on_feature_type_as_string(m_curr_feature->get_type()), Measure::SurfaceFeature(position) }; - break; - } + case EMode::FeatureSelection: { item = { false, m_curr_feature, m_curr_feature }; break; } + case EMode::PointSelection: { item = { false, m_curr_feature, Measure::SurfaceFeature(*m_curr_point_on_feature_position) }; break; } } } return item; }; - if (m_selected_features.first.feature.has_value()) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); - if (it != m_selection_raycasters.end()) - m_selection_raycasters.erase(it); - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, SELECTION_2_ID); + auto requires_sphere_raycaster_for_picking = [this](const SelectedFeatures::Item& item) { + if (m_mode == EMode::PointSelection) + return true; + else if (m_mode == EMode::FeatureSelection) { + if (is_feature_with_center(*item.feature)) + return true; + } + return false; + }; - const SelectedFeatures::Item item = item_from_feature(); + if (m_selected_features.first.feature.has_value()) { + const SelectedFeatures::Item item = detect_current_item(); if (m_selected_features.first != item) { - if (m_selected_features.second == item) - m_selected_features.second.reset(); - else { - m_selected_features.second = item; - if (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) - m_selection_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SELECTION_2_ID, *m_sphere.mesh_raycaster)); - if (m_mode == EMode::CenterSelection) { - // Fake ctrl up event to exit the center selection mode - gizmo_event(SLAGizmoEventType::CtrlUp, Vec2d::Zero(), true, false, false); - // increase counter to avoid that keeping the ctrl key pressed triggers a ctrl down event - m_ctrl_kar_filter.increase_count(); + bool processed = false; + if (item.is_center) { + if (item.source == m_selected_features.first.feature) { + // switch 1st selection from feature to its center + m_selected_features.first = item; + processed = true; + } + else if (item.source == m_selected_features.second.feature) { + // switch 2nd selection from feature to its center + m_selected_features.second = item; + processed = true; + } + } + else if (is_feature_with_center(*item.feature)) { + if (m_selected_features.first.is_center && m_selected_features.first.source == item.feature) { + // switch 1st selection from center to its feature + m_selected_features.first = item; + processed = true; + } + else if (m_selected_features.second.is_center && m_selected_features.second.source == item.feature) { + // switch 2nd selection from center to its feature + m_selected_features.second = item; + processed = true; + } + } + + if (!processed) { + remove_selected_sphere_raycaster(SEL_SPHERE_2_ID); + if (m_selected_features.second == item) + // 2nd feature deselection + m_selected_features.second.reset(); + else { + // 2nd feature selection + m_selected_features.second = item; + if (requires_sphere_raycaster_for_picking(item)) + m_selected_sphere_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SEL_SPHERE_2_ID, *m_sphere.mesh_raycaster)); } } } else { - if (!m_selected_features.second.feature.has_value()) - m_selected_features.first.reset(); - else { + remove_selected_sphere_raycaster(SEL_SPHERE_1_ID); + if (m_selected_features.second.feature.has_value()) { + // promote 2nd feature to 1st feature + remove_selected_sphere_raycaster(SEL_SPHERE_2_ID); m_selected_features.first = m_selected_features.second; + if (requires_sphere_raycaster_for_picking(m_selected_features.first)) + m_selected_sphere_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SEL_SPHERE_1_ID, *m_sphere.mesh_raycaster)); m_selected_features.second.reset(); } + else + // 1st feature deselection + m_selected_features.first.reset(); } } else { - const SelectedFeatures::Item item = item_from_feature(); + // 1st feature selection + const SelectedFeatures::Item item = detect_current_item(); m_selected_features.first = item; - if (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) - m_selection_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SELECTION_1_ID, *m_sphere.mesh_raycaster)); - if (m_mode == EMode::CenterSelection) { - // Fake ctrl up event to exit the center selection mode - gizmo_event(SLAGizmoEventType::CtrlUp, Vec2d::Zero(), true, false, false); - // increase counter to avoid that keeping the ctrl key pressed triggers a ctrl down event - m_ctrl_kar_filter.increase_count(); - } + if (requires_sphere_raycaster_for_picking(item)) + m_selected_sphere_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SEL_SPHERE_1_ID, *m_sphere.mesh_raycaster)); } if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) @@ -399,9 +451,8 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) } else if (mouse_event.RightDown()) { // let the event pass through to allow panning/rotating the 3D scene - if ((m_mode != EMode::CenterSelection && mouse_event.CmdDown()) || (m_mode == EMode::CenterSelection && m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID)) { + if (mouse_event.CmdDown()) return false; - } } else if (mouse_event.Leaving()) m_mouse_left_down = false; @@ -423,7 +474,7 @@ void GLGizmoMeasure::data_changed() } else m_selected_features.reset(); - m_selection_raycasters.clear(); + m_selected_sphere_raycasters.clear(); m_editing_distance = false; m_is_editing_distance_first_frame = true; } @@ -450,7 +501,7 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po if (action == SLAGizmoEventType::ShiftDown) { if (m_shift_kar_filter.is_first()) { - m_mode = activate_center_selection(SLAGizmoEventType::ShiftDown) ? EMode::CenterSelection : EMode::PointSelection; + m_mode = EMode::PointSelection; disable_scene_raycasters(); } m_shift_kar_filter.increase_count(); @@ -460,33 +511,23 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po m_mode = EMode::FeatureSelection; restore_scene_raycasters_state(); } - else if (action == SLAGizmoEventType::CtrlDown) { - if (m_ctrl_kar_filter.is_first()) { - if (activate_center_selection(SLAGizmoEventType::CtrlDown)) { - m_mode = EMode::CenterSelection; - disable_scene_raycasters(); - } - } - m_ctrl_kar_filter.increase_count(); - } - else if (action == SLAGizmoEventType::CtrlUp) { - m_ctrl_kar_filter.reset_count(); - m_mode = control_down ? EMode::PointSelection : EMode::FeatureSelection; - restore_scene_raycasters_state(); - } else if (action == SLAGizmoEventType::Delete) { m_selected_features.reset(); - m_selection_raycasters.clear(); + m_selected_sphere_raycasters.clear(); m_parent.request_extra_frame(); } else if (action == SLAGizmoEventType::Escape) { if (!m_selected_features.first.feature.has_value()) return false; else { - if (m_selected_features.second.feature.has_value()) - m_selected_features.second.feature.reset(); - else - m_selected_features.first.feature.reset(); + if (m_selected_features.second.feature.has_value()) { + remove_selected_sphere_raycaster(SEL_SPHERE_2_ID); + m_selected_features.second.feature.reset(); + } + else { + remove_selected_sphere_raycaster(SEL_SPHERE_1_ID); + m_selected_features.first.feature.reset(); + } } } @@ -503,7 +544,6 @@ void GLGizmoMeasure::on_set_state() { if (m_state == Off) { m_parent.toggle_sla_auxiliaries_visibility(true, nullptr, -1); - m_ctrl_kar_filter.reset_count(); m_shift_kar_filter.reset_count(); m_curr_feature.reset(); m_curr_point_on_feature_position.reset(); @@ -566,7 +606,7 @@ void GLGizmoMeasure::on_render() Vec3f normal_on_model; size_t model_facet_idx; const bool mouse_on_object = m_raycaster->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); - const bool is_hovering_on_feature = (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) && m_hover_id != -1; + const bool is_hovering_on_feature = m_mode == EMode::PointSelection && m_hover_id != -1; auto update_circle = [this, inv_zoom]() { if (m_last_inv_zoom != inv_zoom || m_last_circle != m_curr_feature) { @@ -583,14 +623,13 @@ void GLGizmoMeasure::on_render() }; if (m_mode == EMode::FeatureSelection || m_mode == EMode::PointSelection) { - if ((m_hover_id == SELECTION_1_ID && boost::algorithm::istarts_with(m_selected_features.first.source, _u8L("Center"))) || - (m_hover_id == SELECTION_2_ID && boost::algorithm::istarts_with(m_selected_features.second.source, _u8L("Center")))) { - // Skip feature detection if hovering on a selected center - m_curr_feature.reset(); + if (m_hover_id == SEL_SPHERE_1_ID || m_hover_id == SEL_SPHERE_2_ID) { + // Skip feature detection if hovering on a selected point/center m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); + m_curr_feature.reset(); m_curr_point_on_feature_position.reset(); } else { @@ -618,15 +657,12 @@ void GLGizmoMeasure::on_render() case Measure::SurfaceFeatureType::Edge: { m_raycasters.insert({ EDGE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID, *m_cylinder.mesh_raycaster) }); - if (m_curr_feature->get_extra_point().has_value()) - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); break; } case Measure::SurfaceFeatureType::Circle: { update_circle(); m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); break; } case Measure::SurfaceFeatureType::Plane: @@ -781,72 +817,69 @@ void GLGizmoMeasure::on_render() case Measure::SurfaceFeatureType::Circle: { const auto& [center, radius, normal] = feature.get_circle(); - // render center + // render circle + const Transform3d circle_matrix = Transform3d::Identity(); + set_matrix_uniforms(circle_matrix); if (update_raycasters_transform) { + set_emission_uniform(colors.front(), hover); + m_circle.model.set_color(colors.front()); + m_circle.model.render(); + auto it = m_raycasters.find(CIRCLE_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(circle_matrix); + } + else { + GLModel circle; + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); + circle.init_from(std::move(circle_geometry)); + set_emission_uniform(colors.front(), hover); + circle.set_color(colors.front()); + circle.render(); + } + // render center + if (colors.size() > 1) { const Transform3d center_matrix = Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom); set_matrix_uniforms(center_matrix); - set_emission_uniform(colors.front(), hover); - m_sphere.model.set_color(colors.front()); + set_emission_uniform(colors.back(), hover); + m_sphere.model.set_color(colors.back()); m_sphere.model.render(); auto it = m_raycasters.find(POINT_ID); if (it != m_raycasters.end() && it->second != nullptr) it->second->set_transform(center_matrix); } - // render circle - if (m_mode != EMode::CenterSelection) { - const Transform3d circle_matrix = Transform3d::Identity(); - set_matrix_uniforms(circle_matrix); - if (update_raycasters_transform) { - set_emission_uniform(colors.back(), hover); - m_circle.model.set_color(colors.back()); - m_circle.model.render(); - auto it = m_raycasters.find(CIRCLE_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(circle_matrix); - } - else { - GLModel circle; - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); - circle.init_from(std::move(circle_geometry)); - set_emission_uniform(colors.back(), hover); - circle.set_color(colors.back()); - circle.render(); - } - } break; } case Measure::SurfaceFeatureType::Edge: { const auto& [from, to] = feature.get_edge(); - // render extra point + // render edge + const Transform3d edge_matrix = Geometry::translation_transform(from) * + Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * + Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); + set_matrix_uniforms(edge_matrix); + set_emission_uniform(colors.front(), hover); + m_cylinder.model.set_color(colors.front()); + m_cylinder.model.render(); if (update_raycasters_transform) { + auto it = m_raycasters.find(EDGE_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(edge_matrix); + } + + // render extra point + if (colors.size() > 1) { const std::optional extra = feature.get_extra_point(); if (extra.has_value()) { const Transform3d point_matrix = Geometry::translation_transform(*extra) * Geometry::scale_transform(inv_zoom); set_matrix_uniforms(point_matrix); - set_emission_uniform(colors.front(), hover); - m_sphere.model.set_color(colors.front()); + set_emission_uniform(colors.back(), hover); + m_sphere.model.set_color(colors.back()); m_sphere.model.render(); auto it = m_raycasters.find(POINT_ID); if (it != m_raycasters.end() && it->second != nullptr) it->second->set_transform(point_matrix); } } - // render edge - if (m_mode != EMode::CenterSelection) { - const Transform3d edge_matrix = Geometry::translation_transform(from) * - Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * - Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); - set_matrix_uniforms(edge_matrix); - set_emission_uniform(colors.back(), hover); - m_cylinder.model.set_color(colors.back()); - m_cylinder.model.render(); - if (update_raycasters_transform) { - auto it = m_raycasters.find(EDGE_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(edge_matrix); - } - } break; } case Measure::SurfaceFeatureType::Plane: @@ -878,11 +911,31 @@ void GLGizmoMeasure::on_render() }; if (m_curr_feature.has_value()) { + // render hovered feature + std::vector colors; - if (m_selected_features.first.feature.has_value() && *m_curr_feature == *m_selected_features.first.feature) - colors.emplace_back(hovering_color()); - else if (m_selected_features.second.feature.has_value() && *m_curr_feature == *m_selected_features.second.feature) - colors.emplace_back(hovering_color()); + if (m_selected_features.first.feature.has_value() && *m_curr_feature == *m_selected_features.first.feature) { + // hovering over the 1st selected feature + if (m_selected_features.first.is_center) + // hovering over a center + colors = { NEUTRAL_COLOR, hovering_color() }; + else if (is_feature_with_center(*m_selected_features.first.feature)) + // hovering over a feature with center + colors = { hovering_color(), NEUTRAL_COLOR }; + else + colors = { hovering_color() }; + } + else if (m_selected_features.second.feature.has_value() && *m_curr_feature == *m_selected_features.second.feature) { + // hovering over the 2nd selected feature + if (m_selected_features.second.is_center) + // hovering over a center + colors = { NEUTRAL_COLOR, hovering_color() }; + else if (is_feature_with_center(*m_selected_features.second.feature)) + // hovering over a feature with center + colors = { hovering_color(), NEUTRAL_COLOR }; + else + colors = { hovering_color() }; + } else { switch (m_curr_feature->get_type()) { @@ -895,8 +948,12 @@ void GLGizmoMeasure::on_render() case Measure::SurfaceFeatureType::Edge: case Measure::SurfaceFeatureType::Circle: { - colors.emplace_back((m_hover_id == POINT_ID) ? hover_selection_color() : hovering_color()); - colors.emplace_back(hovering_color()); + if (m_selected_features.first.is_center && m_curr_feature == m_selected_features.first.source) + colors = { SELECTED_1ST_COLOR, NEUTRAL_COLOR }; + else if (m_selected_features.second.is_center && m_curr_feature == m_selected_features.second.source) + colors = { SELECTED_2ND_COLOR, NEUTRAL_COLOR }; + else + colors = { hovering_color(), hovering_color() }; break; } case Measure::SurfaceFeatureType::Plane: @@ -911,28 +968,76 @@ void GLGizmoMeasure::on_render() } if (m_selected_features.first.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.first.feature)) { - const std::vector colors = { SELECTED_1ST_COLOR }; - render_feature(*m_selected_features.first.feature, colors, inv_zoom, m_hover_id == SELECTION_1_ID, false); - if (m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Point) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_1_ID; }); - if (it != m_selection_raycasters.end()) - (*it)->set_transform(Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); + // render 1st selected feature + + std::optional feature_to_render; + std::vector colors; + bool requires_raycaster_update = false; + if (m_hover_id == SEL_SPHERE_1_ID && (m_selected_features.first.is_center || is_feature_with_center(*m_selected_features.first.feature))) { + // hovering over a center + feature_to_render = m_selected_features.first.source; + colors = { NEUTRAL_COLOR, SELECTED_1ST_COLOR }; + requires_raycaster_update = true; + } + else if (is_feature_with_center(*m_selected_features.first.feature)) { + // hovering over a feature with center + feature_to_render = m_selected_features.first.feature; + colors = { SELECTED_1ST_COLOR, NEUTRAL_COLOR }; + requires_raycaster_update = true; + } + else { + feature_to_render = m_selected_features.first.feature; + colors = { SELECTED_1ST_COLOR }; + requires_raycaster_update = m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Point; + } + + render_feature(*feature_to_render, colors, inv_zoom, m_hover_id == SEL_SPHERE_1_ID, false); + + if (requires_raycaster_update) { + auto it = std::find_if(m_selected_sphere_raycasters.begin(), m_selected_sphere_raycasters.end(), + [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SEL_SPHERE_1_ID; }); + if (it != m_selected_sphere_raycasters.end()) + (*it)->set_transform(Geometry::translation_transform(get_feature_offset(*m_selected_features.first.feature)) * Geometry::scale_transform(inv_zoom)); } } + if (m_selected_features.second.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.second.feature)) { - const std::vector colors = { SELECTED_2ND_COLOR }; - render_feature(*m_selected_features.second.feature, colors, inv_zoom, m_hover_id == SELECTION_2_ID, false); - if (m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Point) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); - if (it != m_selection_raycasters.end()) - (*it)->set_transform(Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); + // render 2nd selected feature + + std::optional feature_to_render; + std::vector colors; + bool requires_raycaster_update = false; + if (m_hover_id == SEL_SPHERE_2_ID && (m_selected_features.second.is_center || is_feature_with_center(*m_selected_features.second.feature))) { + // hovering over a center + feature_to_render = m_selected_features.second.source; + colors = { NEUTRAL_COLOR, SELECTED_2ND_COLOR }; + requires_raycaster_update = true; + } + else if (is_feature_with_center(*m_selected_features.second.feature)) { + // hovering over a feature with center + feature_to_render = m_selected_features.second.feature; + colors = { SELECTED_2ND_COLOR, NEUTRAL_COLOR }; + requires_raycaster_update = true; + } + else { + feature_to_render = m_selected_features.second.feature; + colors = { SELECTED_2ND_COLOR }; + requires_raycaster_update = m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Point; + } + + render_feature(*feature_to_render, colors, inv_zoom, m_hover_id == SEL_SPHERE_2_ID, false); + + if (requires_raycaster_update) { + auto it = std::find_if(m_selected_sphere_raycasters.begin(), m_selected_sphere_raycasters.end(), + [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SEL_SPHERE_2_ID; }); + if (it != m_selected_sphere_raycasters.end()) + (*it)->set_transform(Geometry::translation_transform(get_feature_offset(*m_selected_features.second.feature)) * Geometry::scale_transform(inv_zoom)); } } if (is_hovering_on_feature && m_curr_point_on_feature_position.has_value()) { if (m_hover_id != POINT_ID) { + // render point on feature while SHIFT is pressed const Transform3d matrix = Geometry::translation_transform(*m_curr_point_on_feature_position) * Geometry::scale_transform(inv_zoom); set_matrix_uniforms(matrix); const ColorRGBA color = hover_selection_color(); @@ -1597,7 +1702,8 @@ static void add_strings_row_to_table(ImGuiWrapper& imgui, const std::string& col void GLGizmoMeasure::render_debug_dialog() { auto add_feature_data = [this](const SelectedFeatures::Item& item) { - add_strings_row_to_table(*m_imgui, "Type", ImGuiWrapper::COL_ORANGE_LIGHT, item.source, ImGui::GetStyleColorVec4(ImGuiCol_Text)); + const std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id); + add_strings_row_to_table(*m_imgui, "Type", ImGuiWrapper::COL_ORANGE_LIGHT, text, ImGui::GetStyleColorVec4(ImGuiCol_Text)); switch (item.feature->get_type()) { case Measure::SurfaceFeatureType::Point: @@ -1643,7 +1749,6 @@ void GLGizmoMeasure::render_debug_dialog() { case EMode::FeatureSelection: { txt = "Feature selection"; break; } case EMode::PointSelection: { txt = "Point selection"; break; } - case EMode::CenterSelection: { txt = "Center selection"; break; } default: { assert(false); break; } } add_strings_row_to_table(*m_imgui, "Mode", ImGuiWrapper::COL_ORANGE_LIGHT, txt, ImGui::GetStyleColorVec4(ImGuiCol_Text)); @@ -1727,17 +1832,16 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit text = _u8L("Unselect feature"); color = SELECTED_2ND_COLOR; } - else if (m_hover_id == SELECTION_1_ID) { - text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); + else if (m_hover_id == SEL_SPHERE_1_ID) { + text = _u8L("Unselect point"); color = SELECTED_1ST_COLOR; } - else if (m_hover_id == SELECTION_2_ID) { - text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); + else if (m_hover_id == SEL_SPHERE_2_ID) { + text = _u8L("Unselect point"); color = SELECTED_2ND_COLOR; } else { - text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : - (m_mode == EMode::CenterSelection) ? _u8L("Select center") : _u8L("Select feature"); + text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); color = SELECTED_2ND_COLOR; } } @@ -1747,14 +1851,13 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit text = _u8L("Unselect feature"); color = SELECTED_1ST_COLOR; } - else if (m_hover_id == SELECTION_1_ID) { - text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); + else if (m_hover_id == SEL_SPHERE_1_ID) { + text = _u8L("Unselect point"); color = SELECTED_1ST_COLOR; } } if (text.empty()) { - text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : - (m_mode == EMode::CenterSelection) ? _u8L("Select center") : _u8L("Select feature"); + text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); color = m_selected_features.first.feature.has_value() ? SELECTED_2ND_COLOR : SELECTED_1ST_COLOR; } } @@ -1773,11 +1876,6 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ++row_count; } - if (m_mode != EMode::CenterSelection && feature_has_center(m_curr_feature)) { - add_strings_row_to_table(*m_imgui, _u8L("Shift") + "+" + CTRL_STR, ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Enable center selection"), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - ++row_count; - } - if (m_selected_features.first.feature.has_value()) { add_strings_row_to_table(*m_imgui, _u8L("Delete"), ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Restart selection"), ImGui::GetStyleColorVec4(ImGuiCol_Text)); ++row_count; @@ -1803,7 +1901,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit } // add dummy rows to keep dialog size fixed - for (unsigned int i = row_count; i < 5; ++i) { + for (unsigned int i = row_count; i < 4; ++i) { add_strings_row_to_table(*m_imgui, " ", ImGuiWrapper::COL_ORANGE_LIGHT, " ", ImGui::GetStyleColorVec4(ImGuiCol_Text)); } @@ -1816,17 +1914,20 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ImGui::Separator(); const ImGuiTableFlags flags = ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersH; if (ImGui::BeginTable("Selection", 2, flags)) { - auto format_item_text = [use_inches, &units](const SelectedFeatures::Item& item) { - std::string txt = item.feature.has_value() ? item.source : _u8L("None"); - if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) { - auto [center, radius, normal] = item.feature->get_circle(); - const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); - radius = (on_circle - center).norm(); - if (use_inches) - radius = ObjectManipulation::mm_to_in * radius; - txt += " (" + _u8L("Diameter:") + " " + format_double(2.0 * radius) + units + ")"; - } - return txt; + auto format_item_text = [this, use_inches, &units](const SelectedFeatures::Item& item) { + if (!item.feature.has_value()) + return _u8L("None"); + + std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id); + if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) { + auto [center, radius, normal] = item.feature->get_circle(); + const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); + radius = (on_circle - center).norm(); + if (use_inches) + radius = ObjectManipulation::mm_to_in * radius; + text += " (" + _u8L("Diameter:") + " " + format_double(2.0 * radius) + units + ")"; + } + return text; }; add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 1:", ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR), format_item_text(m_selected_features.first), @@ -1839,7 +1940,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit m_imgui->disabled_begin(!m_selected_features.first.feature.has_value()); if (m_imgui->button(_u8L("Restart selection"))) { m_selected_features.reset(); - m_selection_raycasters.clear(); + m_selected_sphere_raycasters.clear(); m_imgui->set_requires_extra_frame(); } m_imgui->disabled_end(); @@ -1935,7 +2036,16 @@ void GLGizmoMeasure::on_unregister_raycasters_for_picking() m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo); m_parent.set_raycaster_gizmos_on_top(false); m_raycasters.clear(); - m_selection_raycasters.clear(); + m_selected_sphere_raycasters.clear(); +} + +void GLGizmoMeasure::remove_selected_sphere_raycaster(int id) +{ + auto it = std::find_if(m_selected_sphere_raycasters.begin(), m_selected_sphere_raycasters.end(), + [id](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == id; }); + if (it != m_selected_sphere_raycasters.end()) + m_selected_sphere_raycasters.erase(it); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, id); } } // namespace GUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 1672e8b74e..1e4330e955 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -24,20 +24,19 @@ class GLGizmoMeasure : public GLGizmoBase enum class EMode : unsigned char { FeatureSelection, - PointSelection, - CenterSelection + PointSelection }; struct SelectedFeatures { struct Item { - std::string source; + bool is_center{ false }; + std::optional source; std::optional feature; bool operator == (const Item& other) const { - if (this->source != other.source) return false; - return this->feature == other.feature; + return this->is_center == other.is_center && this->source == other.source && this->feature == other.feature; } bool operator != (const Item& other) const { @@ -45,7 +44,8 @@ class GLGizmoMeasure : public GLGizmoBase } void reset() { - source.clear(); + is_center = false; + source.reset(); feature.reset(); } }; @@ -106,7 +106,8 @@ class GLGizmoMeasure : public GLGizmoBase std::vector m_plane_models_cache; std::map> m_raycasters; - std::vector> m_selection_raycasters; + // used to keep the raycasters for point/center spheres + std::vector> m_selected_sphere_raycasters; std::optional m_curr_feature; std::optional m_curr_point_on_feature_position; struct SceneRaycasterState @@ -126,7 +127,6 @@ class GLGizmoMeasure : public GLGizmoBase Vec2d m_mouse_pos{ Vec2d::Zero() }; - KeyAutoRepeatFilter m_ctrl_kar_filter; KeyAutoRepeatFilter m_shift_kar_filter; SelectedFeatures m_selected_features; @@ -174,6 +174,8 @@ protected: virtual void on_render_input_window(float x, float y, float bottom_limit) override; virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; + + void remove_selected_sphere_raycaster(int id); }; } // namespace GUI From b3db407327ba5318ad5665de00489f93b20bff1a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 12:51:37 +0100 Subject: [PATCH 37/99] Gizmo measure - Show radius of single selected circle, to allow for object scaling --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 105 ++++++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 1 + 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index eb1a7162eb..04c257e78a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -422,8 +422,7 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) m_selected_sphere_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SEL_SPHERE_1_ID, *m_sphere.mesh_raycaster)); } - if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) - m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); + update_measurement_result(); m_imgui->set_requires_extra_frame(); @@ -469,7 +468,7 @@ void GLGizmoMeasure::data_changed() m_last_inv_zoom = 0.0f; m_last_plane_idx = -1; if (m_pending_scale) { - m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); + update_measurement_result(); m_pending_scale = false; } else @@ -517,8 +516,10 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po m_parent.request_extra_frame(); } else if (action == SLAGizmoEventType::Escape) { - if (!m_selected_features.first.feature.has_value()) + if (!m_selected_features.first.feature.has_value()) { + update_measurement_result(); return false; + } else { if (m_selected_features.second.feature.has_value()) { remove_selected_sphere_raycaster(SEL_SPHERE_2_ID); @@ -528,6 +529,8 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po remove_selected_sphere_raycaster(SEL_SPHERE_1_ID); m_selected_features.first.feature.reset(); } + + update_measurement_result(); } } @@ -1132,7 +1135,10 @@ void GLGizmoMeasure::render_dimensioning() { static SelectedFeatures last_selected_features; - if (!m_selected_features.first.feature.has_value() || !m_selected_features.second.feature.has_value()) + if (!m_selected_features.first.feature.has_value()) + return; + + if (!m_selected_features.second.feature.has_value() && m_selected_features.first.feature->get_type() != Measure::SurfaceFeatureType::Circle) return; GLShaderProgram* shader = wxGetApp().get_shader("flat"); @@ -1340,7 +1346,8 @@ void GLGizmoMeasure::render_dimensioning() const Vec3d new_center = selection.get_bounding_box().center(); const TrafoData trafo_data(ratio, old_center, new_center); scale_feature(*m_selected_features.first.feature, trafo_data); - scale_feature(*m_selected_features.second.feature, trafo_data); + if (m_selected_features.second.feature.has_value()) + scale_feature(*m_selected_features.second.feature, trafo_data); // update measure on next call to data_changed() m_pending_scale = true; @@ -1643,41 +1650,51 @@ void GLGizmoMeasure::render_dimensioning() glsafe(::glDisable(GL_DEPTH_TEST)); - if (m_selected_features.second.feature.has_value()) { - const bool has_distance = m_measurement_result.has_distance_data(); + const bool has_distance = m_measurement_result.has_distance_data(); - const Measure::SurfaceFeature* f1 = &(*m_selected_features.first.feature); - const Measure::SurfaceFeature* f2 = &(*m_selected_features.second.feature); - Measure::SurfaceFeatureType ft1 = f1->get_type(); - Measure::SurfaceFeatureType ft2 = f2->get_type(); - - // Order features by type so following conditions are simple. - if (ft1 > ft2) { - std::swap(ft1, ft2); - std::swap(f1, f2); - } - - // If there is an angle to show, draw the arc: - if (ft1 == Measure::SurfaceFeatureType::Edge && ft2 == Measure::SurfaceFeatureType::Edge) - arc_edge_edge(*f1, *f2); - else if (ft1 == Measure::SurfaceFeatureType::Edge && ft2 == Measure::SurfaceFeatureType::Plane) - arc_edge_plane(*f1, *f2); - else if (ft1 == Measure::SurfaceFeatureType::Plane && ft2 == Measure::SurfaceFeatureType::Plane) - arc_plane_plane(*f1, *f2); - - if (has_distance){ - // Where needed, draw the extension of the edge to where the dist is measured: - if (ft1 == Measure::SurfaceFeatureType::Point && ft2 == Measure::SurfaceFeatureType::Edge) - point_edge(*f1, *f2); - - // Render the arrow between the points that the backend passed: - const Measure::DistAndPoints& dap = m_measurement_result.distance_infinite.has_value() - ? *m_measurement_result.distance_infinite - : *m_measurement_result.distance_strict; - point_point(dap.from, dap.to, dap.dist); - } + const Measure::SurfaceFeature* f1 = &(*m_selected_features.first.feature); + const Measure::SurfaceFeature* f2 = nullptr; + std::unique_ptr temp_feature; + if (m_selected_features.second.feature.has_value()) + f2 = &(*m_selected_features.second.feature); + else { + assert(m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Circle); + temp_feature = std::make_unique(std::get<0>(m_selected_features.first.feature->get_circle())); + f2 = temp_feature.get(); } - + + if (!m_selected_features.second.feature.has_value() && m_selected_features.first.feature->get_type() != Measure::SurfaceFeatureType::Circle) + return; + + Measure::SurfaceFeatureType ft1 = f1->get_type(); + Measure::SurfaceFeatureType ft2 = f2->get_type(); + + // Order features by type so following conditions are simple. + if (ft1 > ft2) { + std::swap(ft1, ft2); + std::swap(f1, f2); + } + + // If there is an angle to show, draw the arc: + if (ft1 == Measure::SurfaceFeatureType::Edge && ft2 == Measure::SurfaceFeatureType::Edge) + arc_edge_edge(*f1, *f2); + else if (ft1 == Measure::SurfaceFeatureType::Edge && ft2 == Measure::SurfaceFeatureType::Plane) + arc_edge_plane(*f1, *f2); + else if (ft1 == Measure::SurfaceFeatureType::Plane && ft2 == Measure::SurfaceFeatureType::Plane) + arc_plane_plane(*f1, *f2); + + if (has_distance){ + // Where needed, draw the extension of the edge to where the dist is measured: + if (ft1 == Measure::SurfaceFeatureType::Point && ft2 == Measure::SurfaceFeatureType::Edge) + point_edge(*f1, *f2); + + // Render the arrow between the points that the backend passed: + const Measure::DistAndPoints& dap = m_measurement_result.distance_infinite.has_value() + ? *m_measurement_result.distance_infinite + : *m_measurement_result.distance_strict; + point_point(dap.from, dap.to, dap.dist); + } + glsafe(::glEnable(GL_DEPTH_TEST)); shader->stop_using(); @@ -2048,5 +2065,15 @@ void GLGizmoMeasure::remove_selected_sphere_raycaster(int id) m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, id); } +void GLGizmoMeasure::update_measurement_result() +{ + if (!m_selected_features.first.feature.has_value()) + m_measurement_result = Measure::MeasurementResult(); + else if (m_selected_features.second.feature.has_value()) + m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); + else if (!m_selected_features.second.feature.has_value() && m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Circle) + m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, Measure::SurfaceFeature(std::get<0>(m_selected_features.first.feature->get_circle())), m_measuring.get()); +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 1e4330e955..4652a171b7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -176,6 +176,7 @@ protected: virtual void on_unregister_raycasters_for_picking() override; void remove_selected_sphere_raycaster(int id); + void update_measurement_result(); }; } // namespace GUI From e6cbf3a215ff6f69e2e8b9060d182c06d180257d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 13:04:48 +0100 Subject: [PATCH 38/99] Fixed warnings --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 04c257e78a..6782d47f19 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -487,17 +487,6 @@ static bool feature_has_center(std::optional feature) bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { - auto activate_center_selection = [this, shift_down, control_down](SLAGizmoEventType action) { - bool ret = false; - switch (action) - { - case SLAGizmoEventType::CtrlDown: { ret = shift_down && feature_has_center(m_curr_feature); break; } - case SLAGizmoEventType::ShiftDown: { ret = control_down && feature_has_center(m_curr_feature); break; } - default: { break; } - } - return ret; - }; - if (action == SLAGizmoEventType::ShiftDown) { if (m_shift_kar_filter.is_first()) { m_mode = EMode::PointSelection; @@ -598,8 +587,6 @@ void GLGizmoMeasure::on_render() // if (m_parent.is_mouse_dragging()) // return; - const Selection& selection = m_parent.get_selection(); - update_if_needed(); const Camera& camera = wxGetApp().plater()->get_camera(); From 681216447fbe9d7fa6182e4c2cdf4427eb3a23ec Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 13:07:49 +0100 Subject: [PATCH 39/99] Fixed warning --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 6782d47f19..4ce33f7cfe 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -310,7 +310,6 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) return false; if (m_hover_id != -1) { - SelectedFeatures selected_features_old = m_selected_features; m_mouse_left_down = true; auto detect_current_item = [this]() { From a78dfa25223ba8417009e42318c3858c9559f9e1 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 13:23:26 +0100 Subject: [PATCH 40/99] Fixed rendering of transparent objects on MAC --- src/slic3r/GUI/3DScene.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index e65a321f1d..7ab01bebf4 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1300,15 +1300,10 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab #endif // ENABLE_GL_CORE_PROFILE #endif // ENABLE_LEGACY_OPENGL_REMOVAL - ScopeGuard transparent_sg; if (type == ERenderType::Transparent) { glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); glsafe(::glDepthMask(false)); - transparent_sg = ScopeGuard([]() { - glsafe(::glDisable(GL_BLEND)); - glsafe(::glDepthMask(true)); - }); } glsafe(::glCullFace(GL_BACK)); @@ -1436,6 +1431,11 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab if (disable_cullface) glsafe(::glEnable(GL_CULL_FACE)); + + if (type == ERenderType::Transparent) { + glsafe(::glDisable(GL_BLEND)); + glsafe(::glDepthMask(true)); + } } bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, ModelInstanceEPrintVolumeState *out_state) const From 4461735dd39376403d019744cd2f2c8aead447b0 Mon Sep 17 00:00:00 2001 From: rtyr <36745189+rtyr@users.noreply.github.com> Date: Wed, 30 Nov 2022 14:36:18 +0100 Subject: [PATCH 41/99] Geeetech bundle https://github.com/prusa3d/PrusaSlicer/pull/9221 --- resources/profiles/Geeetech.idx | 4 + resources/profiles/Geeetech.ini | 1913 +++++++++++++++++ resources/profiles/Geeetech/125X130.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/125x130.svg | 39 + resources/profiles/Geeetech/150x150.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/150x150.svg | 96 + resources/profiles/Geeetech/160x160.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/160x160.svg | 98 + resources/profiles/Geeetech/180X150.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/180x150.svg | 99 + resources/profiles/Geeetech/200x200.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/200x200.svg | 106 + resources/profiles/Geeetech/220x220.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/220x220.svg | 110 + resources/profiles/Geeetech/250x250.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/250x250.svg | 114 + resources/profiles/Geeetech/255x255.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/255x255.svg | 114 + resources/profiles/Geeetech/300x180.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/300x180.svg | 114 + resources/profiles/Geeetech/320x320.stl | Bin 0 -> 684 bytes resources/profiles/Geeetech/320x320.svg | 130 ++ .../profiles/Geeetech/A10M_thumbnail.png | Bin 0 -> 45048 bytes .../profiles/Geeetech/A10Pro_thumbnail.png | Bin 0 -> 33556 bytes .../profiles/Geeetech/A10T_thumbnail.png | Bin 0 -> 42760 bytes .../profiles/Geeetech/A20M_thumbnail.png | Bin 0 -> 42458 bytes .../profiles/Geeetech/A20T_thumbnail.png | Bin 0 -> 57482 bytes resources/profiles/Geeetech/A20_thumbnail.png | Bin 0 -> 40931 bytes .../profiles/Geeetech/A30M_thumbnail.png | Bin 0 -> 49170 bytes .../profiles/Geeetech/A30Pro_thumbnail.png | Bin 0 -> 38513 bytes .../profiles/Geeetech/A30T_thumbnail.png | Bin 0 -> 50478 bytes .../profiles/Geeetech/E180_thumbnail.png | Bin 0 -> 36072 bytes .../Geeetech/GiantArmD200_thumbnail.png | Bin 0 -> 41167 bytes .../profiles/Geeetech/I3ProB_thumbnail.png | Bin 0 -> 59698 bytes .../profiles/Geeetech/I3ProC_thumbnail.png | Bin 0 -> 62464 bytes .../profiles/Geeetech/I3ProW_thumbnail.png | Bin 0 -> 50350 bytes .../Geeetech/MeCreator2_thumbnail.png | Bin 0 -> 48131 bytes .../profiles/Geeetech/MeCreator_thumbnail.png | Bin 0 -> 49215 bytes .../profiles/Geeetech/MeDucer_thumbnail.png | Bin 0 -> 59169 bytes .../profiles/Geeetech/MizarM_thumbnail.png | Bin 0 -> 48858 bytes .../profiles/Geeetech/MizarMax_thumbnail.png | Bin 0 -> 31513 bytes .../profiles/Geeetech/MizarPro_thumbnail.png | Bin 0 -> 35007 bytes .../profiles/Geeetech/MizarS_thumbnail.png | Bin 0 -> 35146 bytes .../profiles/Geeetech/Mizar_thumbnail.png | Bin 0 -> 27120 bytes .../Geeetech/ThunderPro_thumbnail.png | Bin 0 -> 50599 bytes .../profiles/Geeetech/Thunder_thumbnail.png | Bin 0 -> 45095 bytes 46 files changed, 2937 insertions(+) create mode 100644 resources/profiles/Geeetech.idx create mode 100644 resources/profiles/Geeetech.ini create mode 100644 resources/profiles/Geeetech/125X130.stl create mode 100644 resources/profiles/Geeetech/125x130.svg create mode 100644 resources/profiles/Geeetech/150x150.stl create mode 100644 resources/profiles/Geeetech/150x150.svg create mode 100644 resources/profiles/Geeetech/160x160.stl create mode 100644 resources/profiles/Geeetech/160x160.svg create mode 100644 resources/profiles/Geeetech/180X150.stl create mode 100644 resources/profiles/Geeetech/180x150.svg create mode 100644 resources/profiles/Geeetech/200x200.stl create mode 100644 resources/profiles/Geeetech/200x200.svg create mode 100644 resources/profiles/Geeetech/220x220.stl create mode 100644 resources/profiles/Geeetech/220x220.svg create mode 100644 resources/profiles/Geeetech/250x250.stl create mode 100644 resources/profiles/Geeetech/250x250.svg create mode 100644 resources/profiles/Geeetech/255x255.stl create mode 100644 resources/profiles/Geeetech/255x255.svg create mode 100644 resources/profiles/Geeetech/300x180.stl create mode 100644 resources/profiles/Geeetech/300x180.svg create mode 100644 resources/profiles/Geeetech/320x320.stl create mode 100644 resources/profiles/Geeetech/320x320.svg create mode 100644 resources/profiles/Geeetech/A10M_thumbnail.png create mode 100644 resources/profiles/Geeetech/A10Pro_thumbnail.png create mode 100644 resources/profiles/Geeetech/A10T_thumbnail.png create mode 100644 resources/profiles/Geeetech/A20M_thumbnail.png create mode 100644 resources/profiles/Geeetech/A20T_thumbnail.png create mode 100644 resources/profiles/Geeetech/A20_thumbnail.png create mode 100644 resources/profiles/Geeetech/A30M_thumbnail.png create mode 100644 resources/profiles/Geeetech/A30Pro_thumbnail.png create mode 100644 resources/profiles/Geeetech/A30T_thumbnail.png create mode 100644 resources/profiles/Geeetech/E180_thumbnail.png create mode 100644 resources/profiles/Geeetech/GiantArmD200_thumbnail.png create mode 100644 resources/profiles/Geeetech/I3ProB_thumbnail.png create mode 100644 resources/profiles/Geeetech/I3ProC_thumbnail.png create mode 100644 resources/profiles/Geeetech/I3ProW_thumbnail.png create mode 100644 resources/profiles/Geeetech/MeCreator2_thumbnail.png create mode 100644 resources/profiles/Geeetech/MeCreator_thumbnail.png create mode 100644 resources/profiles/Geeetech/MeDucer_thumbnail.png create mode 100644 resources/profiles/Geeetech/MizarM_thumbnail.png create mode 100644 resources/profiles/Geeetech/MizarMax_thumbnail.png create mode 100644 resources/profiles/Geeetech/MizarPro_thumbnail.png create mode 100644 resources/profiles/Geeetech/MizarS_thumbnail.png create mode 100644 resources/profiles/Geeetech/Mizar_thumbnail.png create mode 100644 resources/profiles/Geeetech/ThunderPro_thumbnail.png create mode 100644 resources/profiles/Geeetech/Thunder_thumbnail.png diff --git a/resources/profiles/Geeetech.idx b/resources/profiles/Geeetech.idx new file mode 100644 index 0000000000..dbb458994c --- /dev/null +++ b/resources/profiles/Geeetech.idx @@ -0,0 +1,4 @@ +min_slic3r_version = 2.6.0-alpha1 +0.1.0 Initial Geeetech bundle + + diff --git a/resources/profiles/Geeetech.ini b/resources/profiles/Geeetech.ini new file mode 100644 index 0000000000..0b1ae86c5d --- /dev/null +++ b/resources/profiles/Geeetech.ini @@ -0,0 +1,1913 @@ +# Print profiles for the Geeetech printers. +# Author: Teddy.hu@geeetech.cn (2022.11.23) +# https://github.com/prusa3d/PrusaSlicer/pull/9221 by @alexwoo1900 + +[vendor] +# Vendor name will be shown by the Config Wizard. +name = Geeetech +# Configuration version of this file. Config file will only be installed, if the config_version differs. +# This means, the server may force the PrusaSlicer configuration to be downgraded. +config_version = 0.1.0 +# Where to get the updates from? +config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Geeetech/ + +# The printer models will be shown by the Configuration Wizard in this order, +# also the first model installed & the first nozzle installed will be activated after install. +# Printer model name will be shown by the installation wizard. + +[printer_model:Thunder] +name = Geeetech Thunder +variants = 0.4; 0.2; 0.6; 0.8 +technology = FFF +family = Thunder +bed_model = 250x250.stl +bed_texture = 250x250.svg +default_materials = Thunder HS-PLA @Geeetech; Thunder PLA @Geeetech; Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:ThunderPro] +name = Geeetech Thunder Pro +variants = 0.4; 0.2; 0.6; 0.8 +technology = FFF +family = Thunder +bed_model = 250x250.stl +bed_texture = 250x250.svg +default_materials = Thunder HS-PLA @Geeetech; Thunder PLA @Geeetech; Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:MizarS] +name = Geeetech Mizar S +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = Mizar +bed_model = 255x255.stl +bed_texture = 255x255.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:MizarPro] +name = Geeetech Mizar Pro +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = Mizar +bed_model = 220x220.stl +bed_texture = 220x220.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:Mizar] +name = Geeetech Mizar +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = Mizar +bed_model = 220x220.stl +bed_texture = 220x220.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:MizarMax] +name = Geeetech Mizar Max +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = Mizar +bed_model = 320x320.stl +bed_texture = 320x320.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:MizarM] +name = Geeetech Mizar M +variants = 0.4 +technology = FFF +family = Mizar +bed_model = 255x255.stl +bed_texture = 255x255.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +#[printer_model:MizarT] +#name = Geeetech Mizar T +#variants = 0.4 +#technology = FFF +#family = Mizar +#bed_model = 255x255.stl +#bed_texture = 255x255.svg +#default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A10Pro] +name = Geeetech A10 Pro +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = A10 +bed_model = 220x220.stl +bed_texture = 220x220.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A10M] +name = Geeetech A10 M +variants = 0.4 +technology = FFF +family = A10 +bed_model = 220x220.stl +bed_texture = 220x220.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A10T] +name = Geeetech A10 T +variants = 0.4 +technology = FFF +family = A10 +bed_model = 220x220.stl +bed_texture = 220x220.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A20] +name = Geeetech A20 +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = A20 +bed_model = 250x250.stl +bed_texture = 250x250.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A20M] +name = Geeetech A20 M +variants = 0.4 +technology = FFF +family = A20 +bed_model = 250x250.stl +bed_texture = 250x250.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A20T] +name = Geeetech A20 T +variants = 0.4 +technology = FFF +family = A20 +bed_model = 250x250.stl +bed_texture = 250x250.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A30Pro] +name = Geeetech A30 Pro +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = A30 +bed_model = 320x320.stl +bed_texture = 320x320.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A30M] +name = Geeetech A30 M +variants = 0.4 +technology = FFF +family = A30 +bed_model = 320x320.stl +bed_texture = 320x320.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:A30T] +name = Geeetech A30 T +variants = 0.4 +technology = FFF +family = A30 +bed_model = 320x320.stl +bed_texture = 320x320.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:E180] +name = Geeetech E180 +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = E180 +bed_model = 125X130.stl +bed_texture = 125X130.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:MeDucer] +name = Geeetech Me Ducer +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = Me +bed_model = 180X150.stl +bed_texture = 180X150.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:MeCreator] +name = Geeetech Me Creator +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = Me +bed_model = 150x150.stl +bed_texture = 150x150.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:MeCreator2] +name = Geeetech Me Creator2 +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = Me +bed_model = 160x160.stl +bed_texture = 160x160.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:GiantArmD200] +name = Geeetech GiantArmD200 +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = D200 +bed_model = 300x180.stl +bed_texture = 300x180.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:I3ProB] +name = Geeetech I3 ProB +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = I3 +bed_model = 200x200.stl +bed_texture = 200x200.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:I3ProW] +name = Geeetech I3 ProW +variants = 0.4; 0.2; 0.3; 0.5; 0.6; 0.8 +technology = FFF +family = I3 +bed_model = 200x200.stl +bed_texture = 200x200.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +[printer_model:I3ProC] +name = Geeetech I3 ProC +variants = 0.4 +technology = FFF +family = I3 +bed_model = 200x200.stl +bed_texture = 200x200.svg +default_materials = Generic PLA @Geeetech; Generic PETG @Geeetech; Generic ABS @Geeetech; Generic TPU @Geeetech; Geeetech PLA @Geeetech; Geeetech PETG @Geeetech; Geeetech ABS @Geeetech + +# All presets starting with asterisk, for example *common*, are intermediate and they will not make it into the user interface. + +######################################### +####### Start ###print presets ######## +######################################### + +[print:*common*] +# Print presets for common printers +avoid_crossing_perimeters = 0 +bridge_angle = 0 +bridge_flow_ratio = 0.95 +brim_width = 0 +clip_multipart_objects = 1 +compatible_printers = +complete_objects = 0 +default_acceleration = 500 +dont_support_bridges = 1 +elefant_foot_compensation = 0.1 +ensure_vertical_shell_thickness = 1 +external_fill_pattern = rectilinear +external_perimeters_first = 0 +extra_perimeters = 0 +extruder_clearance_height = 34 +extruder_clearance_radius = 47 +fill_angle = 45 +fill_density = 15% +fill_pattern = grid +gcode_comments = 0 +infill_every_layers = 1 +infill_extruder = 1 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 23% +interface_shells = 0 +min_skirt_length = 4 +notes = +overhangs = 0 +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +perimeter_extruder = 1 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = aligned +single_extruder_multi_material_priming = 0 +skirts = 1 +skirt_distance = 6 +skirt_height = 1 +solid_infill_below_area = 20 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_extruder = 0 +support_material_interface_extruder = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_enforce_layers = 0 +support_material_contact_distance = 0.15 +support_material_interface_contact_loops = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_synchronize_layers = 0 +support_material_threshold = 40 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +thin_walls = 0 +wipe_tower = 0 +xy_size_compensation = 0 +# speed +gap_fill_enabled = 1 +default speed =100 +perimeter_speed = 60 +external_perimeter_speed = 50% +solid_infill_speed = 50% +infill_speed = 80 +top_solid_infill_speed = 25% +support_material_speed = 60 +support_material_interface_speed = 50% +brim_speed = 50% +bridge_speed = 60 +bridge_speed_internal = 100% +overhangs_speed = 100% +gap_fill_speed = 30 +gap_fill_flow_match_perimeter = 0 +thin_walls_speed = 100% +ironing_speed = 50% +travel_speed = 150 +travel_speed_z = 0 +first_layer_min_speed = 0 +first_layer_speed =20 +first_layer_infill_speed = 0 +first_layer_speed_over_raft = 30 +small_perimeter_speed = 25% +small_perimeter_min_length = 6 +small_perimeter_max_length = 20 +max_volumetric_speed = 0 +max_print_speed = 100 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +# extrusion_width +extrusion_width = 0 +extrusion_spacing = +first_layer_extrusion_width = 111% +first_layer_extrusion_spacing = +perimeter_extrusion_width = 111% +perimeter_extrusion_spacing = +external_perimeter_extrusion_width = 105% +external_perimeter_extrusion_spacing = +infill_extrusion_width = 111% +infill_extrusion_spacing = +solid_infill_extrusion_width = 111% +solid_infill_extrusion_spacing = +top_infill_extrusion_width = 105% +top_infill_extrusion_spacing = +support_material_extrusion_width = 0 +skirt_extrusion_width = 130% + +[print:*High-speed*] +# Print presets for high-speed printers. +inherits = *common* +top_solid_layers = 3 +bottom_solid_layers = 3 +gap_fill_enabled = 0 +default_acceleration = 5000 +default speed =250 +perimeter_speed = 230 +external_perimeter_speed = 83% +solid_infill_speed = 80 +infill_speed = 250 +top_solid_infill_speed =100% +support_material_speed = 100 +support_material_interface_speed = 50% +brim_speed = 30% +bridge_speed = 180 +bridge_speed_internal = 120% +overhangs_speed = 120% +gap_fill_speed = 100 +gap_fill_flow_match_perimeter = 0 +thin_walls_speed = 100% +ironing_speed = 75% +travel_speed = 260 +travel_speed_z = 0 +first_layer_min_speed = 0 +first_layer_speed =30 +first_layer_infill_speed = 0 +first_layer_speed_over_raft = 30 +small_perimeter_speed = 65% +max_print_speed = 300 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +small_perimeter_min_length = 8 +small_perimeter_max_length = 25.1327 +solid_infill_below_area = 0 +#travel_speed = {if 120<=infill_speed<=200}200{elsif infill_speed>200}infill_speed{else}150{endif} +#perimeter_speed = {if infill_speed<60}math.ceil(round(infill_speed*0.8){elsif infill_speed>60}math.ceil(round(infill_speed*0.75)){else}60{endif} +#external_perimeter_speed = {if infill_speed<=60}math.ceil(round(infill_speed*0.5)){else}math.ceil(round(infill_speed*0.75)){endif} +#solid_infill_speed = {if infill_speed<=60}20{else}math.ceil(round(infill_speed*0.3)){endif} +#top_solid_infill_speed = {if infill_speed<=60}20{elsif 6060}math.ceil(round(infill_speed*0.5){else}40{endif} +#bridge_speed = {if infill_speed<=60}math.ceil(round(infill_speed*0.5)){else}math.ceil(round(infill_speed*0.75)){endif} +#bridge_speed_internal = {if infill_speed<=60}math.ceil(round(infill_speed*1.5)){elsif 60=2 + +# Print layer_height(0.08mm,0.10mm,0.12mm,0.16mm,0.20mm,0.24mm,0.28mm,0.36mm,0.44mm) +[print:*0.08mm*] +inherits = *common* +layer_height = 0.08 +first_layer_height = 0.12 +bottom_solid_layers = 9 +top_solid_layers = 11 +bridge_flow_ratio = 0.70 + +[print:*0.10mm*] +inherits = *common* +layer_height = 0.10 +first_layer_height = 0.15 +bottom_solid_layers = 7 +top_solid_layers = 9 +bridge_flow_ratio = 0.70 + +[print:*0.12mm*] +inherits = *common* +layer_height = 0.12 +first_layer_height = 0.18 +bottom_solid_layers = 6 +top_solid_layers = 7 +bridge_flow_ratio = 0.70 + +[print:*0.16mm*] +inherits = *common* +layer_height = 0.16 +first_layer_height = 0.16 +bottom_solid_layers = 5 +top_solid_layers = 7 +bridge_flow_ratio = 0.85 + +[print:*0.20mm*] +inherits = *common* +layer_height = 0.20 +first_layer_height = 0.24 +bottom_solid_layers = 4 +top_solid_layers = 5 + +[print:*0.24mm*] +inherits = *common* +layer_height = 0.24 +first_layer_height = 0.30 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:*0.28mm*] +inherits = *common* +layer_height = 0.28 +first_layer_height = 0.30 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:*0.36mm*] +inherits = *common* +layer_height = 0.36 +first_layer_height = 0.36 +bottom_solid_layers = 3 +top_solid_layers = 4 + +[print:*0.44mm*] +inherits = *common* +layer_height = 0.44 +first_layer_height = 0.44 +bottom_solid_layers = 3 +top_solid_layers = 4 + +# Nozzle Size(0.2nozzle,0.3nozzle,0.4nozzle,0.5nozzle,0.6nozzle,0.8nozzle) +[print:*0.2nozzle*] +elefant_foot_compensation = 0 +support_material_interface_layers = 0 +support_material_interface_spacing = 0.15 +support_material_spacing = 1 +support_material_xy_spacing = 150% +support_material_contact_distance = 0.1 +output_filename_format = {input_filename_base}_{nozzle_diameter[0]}nozzle_{layer_height}mm_{initial_filament_type}_{printer_model}_{print_time}.gcode +thick_bridges = 0 +bridge_flow_ratio = 1 +bridge_speed = 20 +wipe_tower_bridging = 6 +wall_transition_angle = 10 +wall_transition_filter_deviation = 25% +wall_transition_length = 0.25 +wall_distribution_count = 1 +min_bead_width = 85% + +[print:*0.3nozzle*] +perimeters = 4 +support_material_interface_spacing = 0.15 +support_material_spacing = 1 +output_filename_format = {input_filename_base}_{nozzle_diameter[0]}nozzle_{layer_height}mm_{initial_filament_type}_{printer_model}_{print_time}.gcode + +[print:*0.4nozzle*] +perimeters = 3 +support_material_interface_spacing = 0.2 +support_material_spacing = 1 +output_filename_format = {input_filename_base}_{nozzle_diameter[0]}nozzle_{digits(layer_height,1,2)}mm_{if num_extruders==1}{filament_type[0]}{elsif num_extruders==2}E0{filament_type[0]}_E1{filament_type[1]}{else}E0{filament_type[0]}_E1{filament_type[1]}E2{filament_type[2]}{endif}_{temperature[0]}C_{printer_model}_{print_time}.gcode + +[print:*0.5nozzle*] +perimeters = 2 +support_material_interface_spacing = 0.25 +support_material_spacing = 1.1 +output_filename_format = {input_filename_base}_{nozzle_diameter[0]}nozzle_{layer_height}mm_{initial_filament_type}_{printer_model}_{print_time}.gcode + +[print:*0.6nozzle*] +perimeters = 2 +support_material_contact_distance = 0.15 +support_material_xy_spacing = 80% +support_material_interface_spacing = 0.3 +output_filename_format = {input_filename_base}_{nozzle_diameter[0]}nozzle_{layer_height}mm_{initial_filament_type}_{printer_model}_{print_time}.gcode +infill_anchor_max = 15 +top_solid_min_thickness = 0.9 +bottom_solid_min_thickness = 0.6 +thick_bridges = 0 +bridge_flow_ratio = 0.95 +bridge_speed = 25 +wall_transition_angle = 10 +wall_transition_filter_deviation = 25% +wall_transition_length = 0.6 +wall_distribution_count = 1 +min_bead_width = 85% + +[print:*0.8nozzle*] +support_material_contact_distance = 0.25 +support_material_spacing = 2 +support_material_interface_spacing = 0.4 +support_material_interface_speed = 100% +support_material_xy_spacing = 80% +support_material_threshold = 50 +output_filename_format = {input_filename_base}_{nozzle_diameter[0]}nozzle_{layer_height}mm_{initial_filament_type}_{printer_model}_{print_time}.gcode +fill_pattern = gyroid +fill_density = 15% +infill_anchor_max = 20 +top_solid_layers = 4 +bottom_solid_layers = 3 +skirt_distance = 3 +skirt_height = 2 +infill_overlap = 30% +bridge_speed = 22 +gap_fill_speed = 30 +bridge_flow_ratio = 0.9 +top_solid_min_thickness = 1.2 +bottom_solid_min_thickness = 0.8 +single_extruder_multi_material_priming = 0 +thick_bridges = 1 +overhangs = 0 +wall_transition_angle = 10 +wall_transition_filter_deviation = 25% +wall_transition_length = 0.8 +wall_distribution_count = 1 +min_bead_width = 85% + +# Print quality of Common printers with different nozzle diameters +[print:0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech] +inherits = *0.08mm*; *0.2nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.2 and num_extruders==1 + +[print:0.08 mm SUPERDETAIL (0.3mm nozzle) @Geeetech] +inherits = *0.08mm*; *0.3nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.3 and num_extruders==1 + +[print:0.08 mm SUPERDETAIL @Geeetech] +inherits = *0.08mm*; *0.4nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.08 mm SUPERDETAIL (0.5mm nozzle) @Geeetech] +inherits = *0.08mm*; *0.5nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.5 and num_extruders==1 + +[print:0.08 mm SUPERDETAIL (0.6mm nozzle) @Geeetech] +inherits = *0.08mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.10 mm HIGHDETAIL (0.2mm nozzle) @Geeetech] +inherits = *0.10mm*; *0.2nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.2 and num_extruders==1 + +[print:0.10 mm HIGHDETAIL (0.3mm nozzle) @Geeetech] +inherits = *0.10mm*; *0.3nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.3 and num_extruders==1 + +[print:0.10 mm HIGHDETAIL @Geeetech] +inherits = *0.10mm*; *0.4nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.10 mm HIGHDETAIL (0.5mm nozzle) @Geeetech] +inherits = *0.10mm*; *0.5nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.5 and num_extruders==1 + +[print:0.10 mm HIGHDETAIL (0.6mm nozzle) @Geeetech] +inherits = *0.10mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.12 mm DETAIL (0.2mm nozzle) @Geeetech] +inherits = *0.12mm*; *0.2nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.2 and num_extruders==1 + +[print:0.12 mm DETAIL (0.3mm nozzle) @Geeetech] +inherits = *0.12mm*; *0.3nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.3 and num_extruders==1 + +[print:0.12 mm DETAIL @Geeetech] +inherits = *0.12mm*; *0.4nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.12 mm DETAIL (0.5mm nozzle) @Geeetech] +inherits = *0.12mm*; *0.5nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.5 and num_extruders==1 + +[print:0.12 mm DETAIL (0.6mm nozzle) @Geeetech] +inherits = *0.12mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.16 mm OPTIMAL (0.2mm nozzle) @Geeetech] +inherits = *0.16mm*; *0.2nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.2 and num_extruders==1 + +[print:0.16 mm OPTIMAL (0.3mm nozzle) @Geeetech] +inherits = *0.16mm*; *0.3nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.3 and num_extruders==1 + +[print:0.16 mm OPTIMAL @Geeetech] +inherits = *0.16mm*; *0.4nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.16 mm OPTIMAL (0.5mm nozzle) @Geeetech] +inherits = *0.16mm*; *0.5nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.5 and num_extruders==1 + +[print:0.16 mm OPTIMAL (0.6mm nozzle) @Geeetech] +inherits = *0.16mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.20 mm NORMAL (0.3mm nozzle) @Geeetech] +inherits = *0.20mm*; *0.3nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.3 and num_extruders==1 + +[print:0.20 mm NORMAL @Geeetech] +inherits = *0.20mm*; *0.4nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.20 mm NORMAL (0.5mm nozzle) @Geeetech] +inherits = *0.20mm*; *0.5nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.5 and num_extruders==1 + +[print:0.20 mm NORMAL (0.6mm nozzle) @Geeetech] +inherits = *0.20mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.24 mm DRAFT @Geeetech] +inherits = *0.24mm*; *0.4nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.24 mm DRAFT (0.5mm nozzle) @Geeetech] +inherits = *0.24mm*; *0.5nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.5 and num_extruders==1 + +[print:0.24 mm DRAFT (0.6mm nozzle) @Geeetech] +inherits = *0.24mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.28 mm SUPERDRAFT @Geeetech] +inherits = *0.28mm*; *0.4nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech] +inherits = *0.28mm*; *0.5nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.5 and num_extruders==1 + +[print:0.28 mm SUPERDRAFT (0.6mm nozzle) @Geeetech] +inherits = *0.28mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.36 mm CHUNKY (0.5mm nozzle) @Geeetech] +inherits = *0.36mm*; *0.5nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.5 and num_extruders==1 + +[print:0.36 mm CHUNKY (0.6mm nozzle) @Geeetech] +inherits = *0.36mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.36 mm CHUNKY (0.8mm nozzle) @Geeetech] +inherits = *0.36mm*; *0.8nozzle* +perimeter_acceleration = 800 +infill_acceleration = 1000 +bridge_acceleration = 1000 +first_layer_acceleration = 800 +default_acceleration = 1000 +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.8 and num_extruders==1 + +[print:0.44 mm SUPERCHUNKY (0.6mm nozzle) @Geeetech] +inherits = *0.44mm*; *0.6nozzle* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech] +inherits = *0.44mm*; *0.8nozzle* +perimeter_acceleration = 800 +infill_acceleration = 1000 +bridge_acceleration = 1000 +first_layer_acceleration = 800 +default_acceleration = 1000 +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.8 and num_extruders==1 + +# Print quality of HighSpeed printers with different nozzle diameters +[print:0.08 mm SUPERDETAIL (0.2mm nozzle) @High-speed] +inherits = *0.08mm*; *0.2nozzle*; *High-speed* +max_volumetric_speed = 15 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.2 and num_extruders==1 + +[print:0.08 mm SUPERDETAIL @High-speed] +inherits = *0.08mm*; *0.4nozzle*; *High-speed* +max_volumetric_speed = 52.8 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.08 mm SUPERDETAIL (0.6mm nozzle) @High-speed] +inherits = *0.08mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.10 mm HIGHDETAIL (0.2mm nozzle) @High-speed] +inherits = *0.10mm*; *0.2nozzle*; *High-speed* +max_volumetric_speed = 15 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.2 and num_extruders==1 + +[print:0.10 mm HIGHDETAIL @High-speed] +inherits = *0.10mm*; *0.4nozzle*; *High-speed* +max_volumetric_speed = 52.8 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.10 mm HIGHDETAIL (0.6mm nozzle) @High-speed] +inherits = *0.10mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.12 mm DETAIL (0.2mm nozzle) @High-speed] +inherits = *0.12mm*; *0.2nozzle*; *High-speed* +max_volumetric_speed = 15 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.2 and num_extruders==1 + +[print:0.12 mm DETAIL @High-speed] +inherits = *0.12mm*; *0.4nozzle*; *High-speed* +max_volumetric_speed = 52.8 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.12 mm DETAIL (0.6mm nozzle) @High-speed] +inherits = *0.12mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.16 mm OPTIMAL (0.2mm nozzle) @High-speed] +inherits = *0.16mm*; *0.2nozzle*; *High-speed* +max_volumetric_speed = 15 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.2 and num_extruders==1 + +[print:0.16 mm OPTIMAL @High-speed] +inherits = *0.16mm*; *0.4nozzle*; *High-speed* +max_volumetric_speed = 52.8 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.16 mm OPTIMAL (0.6mm nozzle) @High-speed] +inherits = *0.16mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.20 mm NORMAL @High-speed] +inherits = *0.20mm*; *0.4nozzle*; *High-speed* +first_layer_height = 0.30 +max_volumetric_speed = 52.8 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.20 mm NORMAL (0.6mm nozzle) @High-speed] +inherits = *0.20mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.24 mm DRAFT @High-speed] +inherits = *0.24mm*; *0.4nozzle*; *High-speed* +max_volumetric_speed = 52.8 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.24 mm DRAFT (0.6mm nozzle) @High-speed] +inherits = *0.24mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.28 mm SUPERDRAFT @High-speed] +inherits = *0.28mm*; *0.4nozzle*; *High-speed* +max_volumetric_speed = 52.8 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.4 and num_extruders==1 + +[print:0.28 mm SUPERDRAFT (0.6mm nozzle) @High-speed] +inherits = *0.28mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.36 mm CHUNKY (0.6mm nozzle) @High-speed] +inherits = *0.36mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.36 mm CHUNKY (0.8mm nozzle) @High-speed] +inherits = *0.36mm*; *0.8nozzle*; *High-speed* +max_volumetric_speed = 216 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.8 and num_extruders==1 + +[print:0.44 mm SUPERCHUNKY (0.6mm nozzle) @High-speed] +inherits = *0.44mm*; *0.6nozzle*; *High-speed* +max_volumetric_speed = 117 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.6 and num_extruders==1 + +[print:0.44 mm SUPERCHUNKY (0.8mm nozzle) @High-speed] +inherits = *0.44mm*; *0.8nozzle*; *High-speed* +max_volumetric_speed = 216 +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ and nozzle_diameter[0]==0.8 and num_extruders==1 + +# Print quality for multi-extruder printers (0.4mm nozzle diameter) +[print:0.08 mm SUPERDETAIL @Multi-extruder] +inherits = *0.08mm*; *0.4nozzle*; *Multi-extruder* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders>=2 + +[print:0.10 mm HIGHDETAIL @Multi-extruder] +inherits = *0.10mm*; *0.4nozzle*; *Multi-extruder* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders>=2 + +[print:0.12 mm DETAIL @Multi-extruder] +inherits = *0.12mm*; *0.4nozzle*; *Multi-extruder* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders>=2 + +[print:0.16 mm OPTIMAL @Multi-extruder] +inherits = *0.16mm*; *0.4nozzle*; *Multi-extruder* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders>=2 + +[print:0.20 mm NORMAL @Multi-extruder] +inherits = *0.20mm*; *0.4nozzle*; *Multi-extruder* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders>=2 + +[print:0.24 mm DETAIL @Multi-extruder] +inherits = *0.24mm*; *0.4nozzle*; *Multi-extruder* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders>=2 + +[print:0.28 mm SUPERDRAFT @Multi-extruder] +inherits = *0.28mm*; *0.4nozzle*; *Multi-extruder* +compatible_printers_condition = printer_model=~/(Mizar|A10|A20|A30|E180|Me|GiantArm|I3).*/ and nozzle_diameter[0]==0.4 and num_extruders>=2 +######################################### +####### End ###print presets ######## +######################################### + + +# When submitting new filaments please print the following temperature tower at 0.1mm layer height: +# https://www.thingiverse.com/thing:2615842 +# Pay particular attention to bridging, overhangs and retractions. +# Also print the following bed adhesion test at 0.1 layer height as well: +# https://www.prusaprinters.org/prints/4634-bed-adhesion-warp-test +# At least for PLA, please keep bed temp at 60℃, as many Geeetech printers do not have any ABL +# So having some leeway to get good bed adhesion is not a luxury for many users + + +######################################### +####### Start ###filament presets ####### +######################################### +[filament:*common*] +# Filament presets for common printers +cooling = 0 +filament_vendor = Generic +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_Geeetech.*/ +extrusion_multiplier = 1 +filament_cost = 0 +filament_density = 0 +filament_diameter = 1.75 +filament_notes = "" +filament_settings_id = "" +filament_soluble = 0 +min_print_speed = 15 +slowdown_below_layer_time = 20 +filament_minimal_purge_on_wipe_tower = 25 + +[filament:*PLA*] +inherits = *common* +fan_below_layer_time = 100 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 0 +filament_type = PLA +filament_density = 1.24 +filament_cost = 20 +first_layer_temperature = 210 +temperature = 205 +first_layer_bed_temperature = 60 +bed_temperature = 60 +fan_always_on = 1 +cooling = 1 +max_fan_speed = 100 +min_fan_speed = 100 +bridge_fan_speed = 100 +disable_fan_first_layers = 2 + +[filament:*PETG*] +inherits = *common* +bed_temperature = 70 +cooling = 1 +disable_fan_first_layers = 3 +fan_below_layer_time = 20 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 0 +filament_type = PETG +filament_density = 1.27 +filament_cost = 30 +first_layer_bed_temperature = 70 +first_layer_temperature = 240 +fan_always_on = 1 +max_fan_speed = 50 +min_fan_speed = 20 +bridge_fan_speed = 100 +temperature = 240 + +[filament:*ABS*] +inherits = *common* +bed_temperature = 100 +cooling = 0 +disable_fan_first_layers = 3 +fan_below_layer_time = 20 +filament_colour = #DDDDDD +filament_max_volumetric_speed = 0 +filament_type = ABS +filament_density = 1.04 +filament_cost = 20 +first_layer_bed_temperature = 100 +first_layer_temperature = 245 +fan_always_on = 0 +max_fan_speed = 0 +min_fan_speed = 0 +bridge_fan_speed = 30 +top_fan_speed = 0 +temperature = 245 + +[filament:*TPU*] +inherits = *common* +bed_temperature = 55 +cooling = 0 +disable_fan_first_layers = 3 +fan_always_on = 0 +fan_below_layer_time = 20 +filament_colour = #CFFFFB +filament_cost = 30 +filament_density = 1.2 +filament_max_volumetric_speed = 0 +filament_retract_before_travel = 4 +filament_retract_length = 2.5 +filament_retract_speed = 30 +filament_type = TPU +first_layer_bed_temperature = 55 +first_layer_temperature = 210 +max_fan_speed = 70 +min_fan_speed = 0 + +[filament:*HS-PLA*] +inherits = *common* +filament_vendor = Geeetech +filament_colour = #F94D0C +filament_max_volumetric_speed = 0 +filament_type = PLA +filament_density = 1.24 +filament_cost = 20 +first_layer_temperature = 210 +temperature = 215 +first_layer_bed_temperature = 60 +bed_temperature = 60 +cooling = 1 +fan_always_on = 1 +min_fan_speed = 100 +bridge_fan_speed = 100 +bridge_internal_fan_speed = -1 +top_fan_speed = -1 +external_perimeter_fan_speed = -1 +support_material_interface_fan_speed = -1 +disable_fan_first_layers = 1 +full_fan_speed_layer = 0 +fan_below_layer_time = 10 +max_fan_speed = 100 +slowdown_below_layer_time = 1 +max_speed_reduction = 15 +min_print_speed = 211 +#"material_print_temperature": {"default_value": 210,"value": "200 if speed_infill <=150 else 205 if speed_infill <= 200 else 215 if speed_infill <= 260 else 220","maximum_value": "250" }, + +[filament:Generic PLA @Geeetech] +inherits = *PLA* +filament_vendor = Generic +filament_cost = 25.4 +filament_density = 1.24 +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_Geeetech.*/ and printer_model=~/(Thunder|ThunderPro|Mizar|A10|A20|A30).*/ + +[filament:Generic PETG @Geeetech] +inherits = *PETG* +filament_vendor = Generic +filament_cost = 27.82 +filament_density = 1.27 + +[filament:Generic ABS @Geeetech] +inherits = *ABS* +filament_vendor = Generic +filament_cost = 27.82 +filament_density = 1.04 + +[filament:Generic TPU @Geeetech] +inherits = *TPU* +filament_vendor = Geeetech + +[filament:Geeetech PLA @Geeetech] +inherits = *PLA* +filament_vendor = Geeetech +temperature = 200 +bed_temperature = 60 +first_layer_temperature = 205 +first_layer_bed_temperature = 60 +filament_colour = #42BDD8 + +[filament:Geeetech PETG @Geeetech] +inherits = *PETG* +filament_vendor = Geeetech +temperature = 240 +bed_temperature = 70 +first_layer_temperature = 240 +first_layer_bed_temperature = 70 +max_fan_speed = 40 +min_fan_speed = 20 +filament_colour = #42BDD8 + +[filament:Geeetech ABS @Geeetech] +inherits = *ABS* +filament_vendor = Geeetech +temperature = 240 +bed_temperature = 100 +first_layer_temperature = 240 +first_layer_bed_temperature = 100 +filament_colour = #42BDD8 + +[filament:Thunder HS-PLA @Geeetech] +inherits = *HS-PLA* +filament_vendor = Geeetech +filament_colour = #F5DC1E +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ +compatible_prints_condition = infill_speed >= 150 +filament_notes = "HS-PLA is Geeetech's latest high-speed printing filament. By adjusting the melting point, melting index, glass transition temperature of raw materials and optimizing the production process, Geeetech enables HS-PLA to have stronger fluidity, smoother discharge, faster curing and forming speed and is not easy to deform under the melting condition. Compared with ordinary PLA, HS-pla has the advantages of faster printing speed, higher printing quality and more delicate model surface, which can better meet the high performance requirements of high-speed 3D printers for filament.\n\nhttps://www.geeetech.com/wiki/index.php/Geeetech_Thunder_3D_printer#HS-PLA_Series_Filament_.22Speed-Temperature.22_Parameter_Settings_for_Reference" + +[filament:Thunder PLA @Geeetech] +inherits = *HS-PLA* +filament_vendor = Geeetech +filament_colour = #C8CF0A +compatible_printers_condition = printer_model=~/(Thunder|ThunderPro).*/ +compatible_prints_condition = infill_speed >= 150 +filament_notes = "common PLA filament setting for high-speed printing" + +######################################### +####### end ###filament presets ######## +######################################### + + + + + +######################################### +########## begin ###printer presets ##### +######################################### +[printer:*common*] +# Presets for common printers +printer_technology = FFF +before_layer_gcode = \nG92 E0\n +between_objects_gcode = +pause_print_gcode = +deretract_speed = 40 +extruder_offset = 0x0 +gcode_flavor = marlin +silent_mode = 0 +remaining_times = 0 +machine_max_feedrate_x = 500 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 5 +machine_max_feedrate_e = 25 +machine_max_acceleration_x = 500 +machine_max_acceleration_y = 500 +machine_max_acceleration_z = 100 +machine_max_acceleration_e = 1000 +machine_max_acceleration_extruding = 500 +machine_max_acceleration_retracting = 1000 +machine_max_jerk_x = 10 +machine_max_jerk_y = 10 +machine_max_jerk_z = 0.3 +machine_max_jerk_e = 5 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩AFTER_LAYER_CHANGE# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +max_print_height = 260 +printer_notes = +printer_settings_id = +retract_before_travel = 2 +retract_before_wipe = 70% +retract_layer_change = 1 +retract_length_toolchange = 1 +retract_lift = 0 +retract_lift_above = 0 +retract_lift_below = 0 +retract_restart_extra = 0 +retract_restart_extra_toolchange = 0 +retract_speed = 45 +single_extruder_multi_material = 0 +toolchange_gcode = +use_firmware_retraction = 0 +use_relative_e_distances = 1 +use_volumetric_e = 0 +variable_layer_height = 1 +z_offset = 0 +printer_model = +default_filament_profile = Generic PLA @Geeetech +start_gcode = ;Custom Start G-code\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG92 E0 ; Reset Extruder\nG28 ; Home all axes\nM107 ;Off Fan\nG1 Z5.0 F3000 ;Move Z Axis up little to prevent scratching of Heat Bed\nG1 X0.1 Y20 Z0.8 F5000 ; Move to start position\nG1 X0.1 Y200.0 Z1.2 F1500 E30 ; Draw the first line\nG92 E0 ; Reset Extruder\nG1 X0.4 Y200.0 Z1.2 F3000 ; Move to side a little\nG1 X0.4 Y20 Z1.2 F1500 E25 ; Draw the second line\nG92 E0 ; Reset Extruder\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X5 Y20 Z0.4 F3000.0 ; Move over to prevent blob squish\n\nM221 S{if layer_height<0.2}110{else}100{endif}\nG92 E0 +end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+min(max_layer_z+70, max_print_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{max_print_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + +[printer:*HighSpeedPrinter*] +# Presets for high-speed printers +inherits = *common* +machine_max_feedrate_x = 300 +machine_max_feedrate_y = 500 +machine_max_feedrate_z = 10 +machine_max_feedrate_e = 60 +machine_max_acceleration_x = 5000 +machine_max_acceleration_y = 4000 +machine_max_acceleration_z = 50 +machine_max_acceleration_e = 3500 +machine_max_acceleration_extruding = 3500 +machine_max_acceleration_retracting = 3500 +machine_max_jerk_x = 45 +machine_max_jerk_y = 45 +machine_max_jerk_z = 0.8 +machine_max_jerk_e = 8 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 5 +extruder_colour = #F5DC1E +default_filament_profile = Thunder HS-PLA @Geeetech; Thunder PLA @Geeetech +start_gcode = ;Custom Start G-code for High-speed Printer\n\nM104 S[first_layer_temperature] ; Set Hotend Temp.\nM140 S[first_layer_bed_temperature] ; Set bed Temp.\nM190 S[first_layer_bed_temperature] ; Wait for Bed Temp.\nM109 S[first_layer_temperature] ; Wait for Hotend Temp.\nG92 E0 ; Reset Extruder\nG28 ; Home all axes\nM107 P0 ;Off Main Fan\nM107 P1 ;Off Aux Fan\nM2012 P8 S1 F100 ; ON Light\n;M106 P0 S383 ; ON MainFan 150% if need\n;M106 P1 S255 ; ON Aux Fan 100% if need\nG1 Z5.0 F3000 ;Move the Z-axis slightly up to prevent scratching the heatbed\nG1 X0.1 Y20 Z0.8 F5000 ; Move to start position\nG1 X0.1 Y200.0 Z1.2 F1500 E30 ; Draw the first line\nG92 E0 ; Reset Extruder\nG1 X0.4 Y200.0 Z1.2 F3000 ; Move to side a little\nG1 X0.4 Y20 Z1.2 F1500 E25 ; Draw the second line\nG92 E0 ; Reset Extruder\nG1 Z2.0 F3000 ; Move the Z-axis slightly up to prevent scratching the heatbed\nG1 X5 Y20 Z0.4 F3000.0 ; Scrape off nozzle residue\n\nM221 S{if layer_height<0.2}110{else}100{endif}\nG92 E0 +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_Thunder series + +[printer:*DualExtruderPrinter*] +# Presets for Dual-Extruder printers +inherits = *common* +deretract_speed = 30,30 +extruder_offset = 0x0,0x0 +max_layer_height = 0.3,0.3 +min_layer_height = 0.05,0.05 +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MizarM&A10M&A20M&A30M +retract_before_travel = 3,3 +retract_before_wipe = 15%,15% +retract_layer_change = 0,0 +retract_length = 6,6 +retract_length_toolchange = 0,0 +retract_lift = 0,0 +retract_restart_extra = 0,0 +retract_restart_extra_toolchange = 0,0 +retract_speed = 35,35 +use_relative_e_distances = 1 +wipe = 0,0 +z_offset = 0 +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech + +[printer:*MultiExtruderPrinter*] +# Presets for Multi-Extruder printers +inherits = *common* +deretract_speed = 30,30,30 +extruder_offset = 0x0,0x0,0x0 +max_layer_height = 0.3,0.3 +min_layer_height = 0.05,0.05 +printer_notes = Do not remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MizarT&A10T&A20T&A30T +retract_before_travel = 3,3,3 +retract_before_wipe = 15%,15%,15% +retract_layer_change = 0,0,0 +retract_length = 6,6,6 +retract_length_toolchange = 0,0,0 +retract_lift = 0,0,0 +retract_restart_extra = 0,0,0 +retract_restart_extra_toolchange = 0,0,0 +retract_speed = 35,35,35 +use_relative_e_distances = 1 +wipe = 0,0,0 +z_offset = 0 +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech + +# Intended for printers where the Z-axis lowers the print bed during printing, like the GTC10 series +#[printer:*descendingz*] +#end_gcode = {if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F{travel_speed*60} ; move print head out of the way\n{if max_layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed close to the bottom\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors + +[printer:*PausePrint*] +# Intended for printers with vendor official firmware verified to support M25 +pause_print_gcode = M25 ; pause print + +# Presets retract length +[printer:*Retract_1mm*] +retract_length = 1 +[printer:*Retract_2mm*] +retract_length = 2 +[printer:*Retract_3mm*] +retract_length = 3 +[printer:*Retract_4mm*] +retract_length = 4 +[printer:*Retract_5mm*] +retract_length = 5 +[printer:*Retract_6mm*] +retract_length = 6 + +[printer:*Retract_6.5mm*] +retract_length = 6.5 + +[printer:*Retract_7mm*] +retract_length = 7 + +[printer:*Retract_8mm*] +retract_length = 8 + +[printer:*0.2nozzle*] +nozzle_diameter = 0.2 +printer_variant = 0.2 +min_layer_height = 0.08 +max_layer_height = 0.16 +retract_lift_above = 0.2 + +[printer:*0.3nozzle*] +nozzle_diameter = 0.3 +printer_variant = 0.3 +min_layer_height = 0.08 +max_layer_height = 0.24 +retract_lift_above = 0.2 + +[printer:*0.4nozzle*] +nozzle_diameter = 0.4 +printer_variant = 0.4 +min_layer_height = 0.08 +max_layer_height = 0.32 +retract_lift_above = 0.2 + +[printer:*0.5nozzle*] +nozzle_diameter = 0.5 +printer_variant = 0.5 +min_layer_height = 0.08 +max_layer_height = 0.40 +retract_lift_above = 0.2 + +[printer:*0.6nozzle*] +nozzle_diameter = 0.6 +printer_variant = 0.6 +min_layer_height = 0.08 +max_layer_height = 0.48 +retract_lift_above = 0.3 + +[printer:*0.8nozzle*] +nozzle_diameter = 0.8 +printer_variant = 0.8 +min_layer_height = 0.08 +max_layer_height = 0.48 +retract_lift_above = 0.3 + +######################################### +###############Printer inherits########## +######################################### + +[printer:*Thunder*] +inherits = *common*; *HighSpeedPrinter*; *Retract_6.5mm*; *PausePrint* +printer_model = Thunder +bed_shape = 0x0,250x0,250x250,0x250 +max_print_height = 260 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【Thunder】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_Thunder\nPRINTER_HAS_BOWDEN + +[printer:*ThunderPro*] +inherits = *common*; *HighSpeedPrinter*; *Retract_6.5mm*; *PausePrint* +printer_model = ThunderPro +bed_shape = 0x0,250x0,250x250,0x250 +max_print_height = 260 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【ThunderPro】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_ThunderPro\nPRINTER_HAS_DirectDriveExtruder + +[printer:*MizarS*] +inherits = *common*; *Retract_6.5mm*; *PausePrint* +printer_model = MizarS +bed_shape = 0x0,255x0,255x255,0x255 +max_print_height = 260 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【MizarS】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MizarS\nPRINTER_HAS_BOWDEN + +[printer:*MizarPro*] +inherits = *common*; *Retract_6.5mm*; *PausePrint* +printer_model = MizarPro +bed_shape = 0x0,220x0,220x220,0x220 +max_print_height = 260 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【Mizar Pro】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MizarPro\nPRINTER_HAS_BOWDEN + +[printer:*Mizar*] +inherits = *common*; *Retract_6.5mm*; *PausePrint* +printer_model = Mizar +bed_shape = 0x0,220x0,220x220,0x220 +max_print_height = 260 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【Mizar】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_Mizar\nPRINTER_HAS_BOWDEN + +[printer:*MizarMax*] +inherits = *common*; *Retract_6.5mm*; *PausePrint* +printer_model = MizarMax +bed_shape = 0x0,320x0,320x320,0x320 +max_print_height = 400 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【MizarMax】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MizarMax\nPRINTER_HAS_BOWDEN + +[printer:*A10Pro*] +inherits = *common*; *Retract_6.5mm*; *PausePrint* +printer_model = A10Pro +bed_shape = 0x0,220x0,220x220,0x220 +max_print_height = 260 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A10 Pro】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A10Pro\nPRINTER_HAS_BOWDEN + +[printer:*A20*] +inherits = *common*; *Retract_6.5mm*; *PausePrint* +printer_model = A20 +bed_shape = 0x0,250x0,250x250,0x250 +max_print_height = 250 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A20】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A20\nPRINTER_HAS_BOWDEN + +[printer:*A30Pro*] +inherits = *common*; *Retract_6.5mm*; *PausePrint* +printer_model = A30Pro +bed_shape = 0x0,320x0,320x320,0x320 +max_print_height = 420 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A30Pro】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A30Pro\nPRINTER_HAS_BOWDEN + +[printer:*E180*] +inherits = *common*; *Retract_6mm*; *PausePrint* +printer_model = E180 +bed_shape = 0x0,125x0,125x130,0x130 +max_print_height = 126 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【E180】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_E180\nPRINTER_HAS_BOWDEN + +[printer:*MeDucer*] +inherits = *common*; *Retract_2mm*; *PausePrint* +printer_model = MeDucer +bed_shape = 0x0,180x0,180x150,0x150 +max_print_height = 150 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【MeDucer】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MeDucer\nPRINTER_HAS_DirectDriveExtruder + +[printer:*MeCreator*] +inherits = *common*; *Retract_2mm*; *PausePrint* +printer_model = MeCreator +bed_shape = 0x0,150x0,150x150,0x150 +max_print_height = 125 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【MeCreator】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MeCreator\nPRINTER_HAS_DirectDriveExtruder + +[printer:*MeCreator2*] +inherits = *common*; *Retract_2mm*; *PausePrint* +printer_model = MeCreator2 +bed_shape = 0x0,160x0,160x160,0x160 +max_print_height = 160 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【MeCreator2】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MeCreator2\nPRINTER_HAS_DirectDriveExtruder + +[printer:*GiantArmD200*] +inherits = *common*; *Retract_2mm*; *PausePrint* +printer_model = GiantArmD200 +bed_shape = 0x0,300x0,300x180,0x180 +max_print_height = 180 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【GiantArmD200】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_GiantArmD200\nPRINTER_HAS_DirectDriveExtruder + +[printer:*I3ProB*] +inherits = *common*; *Retract_2mm*; *PausePrint* +printer_model = I3ProB +bed_shape = 0x0,200x0,200x200,0x200 +max_print_height = 180 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【I3ProB】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_I3ProB\nPRINTER_HAS_DirectDriveExtruder + +[printer:*I3ProW*] +inherits = *common*; *Retract_2mm*; *PausePrint* +printer_model = I3ProW +bed_shape = 0x0,200x0,200x200,0x200 +max_print_height = 180 +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【I3ProW】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_I3ProW\nPRINTER_HAS_DirectDriveExtruder + + + +[printer:Geeetech Thunder (0.2 mm nozzle)] +inherits = *Thunder*; *0.2nozzle* +default_print_profile = 0.10 mm HIGHDETAIL (0.2mm nozzle) @High-speed +default_filament_profile =Thunder HS-PLA @Geeetech +[printer:Geeetech Thunder] +inherits = *Thunder*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @High-speed +default_filament_profile =Thunder HS-PLA @Geeetech +[printer:Geeetech Thunder (0.6 mm nozzle)] +inherits = *Thunder*; *0.6nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.6mm nozzle) @High-speed +default_filament_profile =Thunder HS-PLA @Geeetech +[printer:Geeetech Thunder (0.8 mm nozzle)] +inherits = *Thunder*; *0.8nozzle* +default_print_profile = 0.36 mm CHUNKY (0.8mm nozzle) @High-speed +default_filament_profile =Thunder HS-PLA @Geeetech + +[printer:Geeetech ThunderPro (0.2 mm nozzle)] +inherits = *ThunderPro*; *0.2nozzle* +default_print_profile = 0.10 mm HIGHDETAIL (0.2mm nozzle) @High-speed +default_filament_profile =Thunder HS-PLA @Geeetech +[printer:Geeetech ThunderPro] +inherits = *ThunderPro*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @High-speed +default_filament_profile =Thunder HS-PLA @Geeetech +[printer:Geeetech ThunderPro (0.6 mm nozzle)] +inherits = *ThunderPro*; *0.6nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.6mm nozzle) @High-speed +default_filament_profile =Thunder HS-PLA @Geeetech +[printer:Geeetech ThunderPro (0.8 mm nozzle)] +inherits = *ThunderPro*; *0.8nozzle* +default_print_profile = 0.36 mm CHUNKY (0.8mm nozzle) @High-speed +default_filament_profile =Thunder HS-PLA @Geeetech + +[printer:Geeetech MizarS (0.2 mm nozzle)] +inherits = *MizarS*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarS (0.3 mm nozzle)] +inherits = *MizarS*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarS] +inherits = *MizarS*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarS (0.5 mm nozzle)] +inherits = *MizarS*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarS (0.6 mm nozzle)] +inherits = *MizarS*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarS (0.8 mm nozzle)] +inherits = *MizarS*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech MizarPro (0.2 mm nozzle)] +inherits = *MizarPro*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarPro (0.3 mm nozzle)] +inherits = *MizarPro*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarPro] +inherits = *MizarPro*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarPro (0.5 mm nozzle)] +inherits = *MizarPro*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarPro (0.6 mm nozzle)] +inherits = *MizarPro*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarPro (0.8 mm nozzle)] +inherits = *MizarPro*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech Mizar (0.2 mm nozzle)] +inherits = *Mizar*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech Mizar (0.3 mm nozzle)] +inherits = *Mizar*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech Mizar] +inherits = *Mizar*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech Mizar (0.5 mm nozzle)] +inherits = *Mizar*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech Mizar (0.6 mm nozzle)] +inherits = *Mizar*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech Mizar (0.8 mm nozzle)] +inherits = *Mizar*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech MizarMax (0.2 mm nozzle)] +inherits = *MizarMax*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarMax (0.3 mm nozzle)] +inherits = *MizarMax*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarMax] +inherits = *MizarMax*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarMax (0.5 mm nozzle)] +inherits = *MizarMax*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarMax (0.6 mm nozzle)] +inherits = *MizarMax*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MizarMax (0.8 mm nozzle)] +inherits = *MizarMax*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech MizarM] +inherits = *common*; *DualExtruderPrinter*; *0.4nozzle*; *Retract_6mm*; *PausePrint* +printer_model = MizarM +bed_shape = 0x0,255x0,255x255,0x255 +max_print_height = 260 +nozzle_diameter = 0.4,0.4 +extruder_colour = #FF8000;#DB5182 +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【MizarM】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MizarM\nPRINTER_HAS_BOWDEN + +## [printer:Geeetech MizarT] +## inherits = *common*; *MultiExtruderPrinter*; *0.4nozzle*; *Retract_6mm*; *PausePrint* +## printer_model = MizarT +## bed_shape = 0x0,255x0,255x255,0x255 +## max_print_height = 260 +## nozzle_diameter = 0.4,0.4,0.4 +## extruder_colour = #FF0000;#00FF00;#0000FF +## default_print_profile = 0.20 mm NORMAL @Multi-extruder +## default_filament_profile = Generic PLA @Geeetech +## layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【MizarT】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +## printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_MizarT\nPRINTER_HAS_BOWDEN + +[printer:Geeetech A10Pro (0.2 mm nozzle)] +inherits = *A10Pro*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A10Pro (0.3 mm nozzle)] +inherits = *A10Pro*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A10Pro] +inherits = *A10Pro*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A10Pro (0.5 mm nozzle)] +inherits = *A10Pro*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A10Pro (0.6 mm nozzle)] +inherits = *A10Pro*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A10Pro (0.8 mm nozzle)] +inherits = *A10Pro*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech A10M] +inherits = *common*; *DualExtruderPrinter*; *0.4nozzle*; *Retract_6mm*; *PausePrint* +printer_model = A10M +bed_shape = 0x0,220x0,220x220,0x220 +max_print_height = 260 +nozzle_diameter = 0.4,0.4 +extruder_colour = #FF8000;#DB5182 +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A10M】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A10M\nPRINTER_HAS_BOWDEN + +[printer:Geeetech A10T] +inherits = *common*; *MultiExtruderPrinter*; *0.4nozzle*; *Retract_6mm*; *PausePrint* +printer_model = A10T +bed_shape = 0x0,220x0,220x220,0x220 +max_print_height = 260 +nozzle_diameter = 0.4,0.4,0.4 +extruder_colour = #FF0000;#00FF00;#0000FF +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A10T】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A10T\nPRINTER_HAS_BOWDEN + +[printer:Geeetech A20 (0.2 mm nozzle)] +inherits = *A20*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A20 (0.3 mm nozzle)] +inherits = *A20*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A20] +inherits = *A20*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A20 (0.5 mm nozzle)] +inherits = *A20*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A20 (0.6 mm nozzle)] +inherits = *A20*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A20 (0.8 mm nozzle)] +inherits = *A20*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech A20M] +inherits = *common*; *DualExtruderPrinter*; *0.4nozzle*; *Retract_6mm*; *PausePrint* +printer_model = A20M +bed_shape = 0x0,250x0,250x250,0x250 +max_print_height = 250 +nozzle_diameter = 0.4,0.4 +extruder_colour = #FF8000;#DB5182 +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A20M】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A20M\nPRINTER_HAS_BOWDEN + +[printer:Geeetech A20T] +inherits = *common*; *MultiExtruderPrinter*; *0.4nozzle*; *Retract_6mm*; *PausePrint* +printer_model = A20T +bed_shape = 0x0,250x0,250x250,0x250 +max_print_height = 250 +nozzle_diameter = 0.4,0.4,0.4 +extruder_colour = #FF0000;#00FF00;#0000FF +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A20T】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A20T\nPRINTER_HAS_BOWDEN + +[printer:Geeetech A30Pro (0.2 mm nozzle)] +inherits = *A30Pro*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A30Pro (0.3 mm nozzle)] +inherits = *A30Pro*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A30Pro] +inherits = *A30Pro*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A30Pro (0.5 mm nozzle)] +inherits = *A30Pro*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A30Pro (0.6 mm nozzle)] +inherits = *A30Pro*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech A30Pro (0.8 mm nozzle)] +inherits = *A30Pro*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech A30M] +inherits = *common*; *DualExtruderPrinter*; *0.4nozzle*; *Retract_6mm*; *PausePrint* +printer_model = A30M +bed_shape = 0x0,320x0,320x320,0x320 +max_print_height = 420 +nozzle_diameter = 0.4,0.4 +extruder_colour = #FF8000;#DB5182 +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A30M】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A30M\nPRINTER_HAS_BOWDEN + +[printer:Geeetech A30T] +inherits = *common*; *MultiExtruderPrinter*; *0.4nozzle*; *Retract_6mm*; *PausePrint* +printer_model = A30T +bed_shape = 0x0,320x0,320x320,0x320 +max_print_height = 420 +nozzle_diameter = 0.4,0.4,0.4 +extruder_colour = #FF0000;#00FF00;#0000FF +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【A30T】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_A30T\nPRINTER_HAS_BOWDEN + +[printer:Geeetech E180 (0.2 mm nozzle)] +inherits = *E180*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech E180 (0.3 mm nozzle)] +inherits = *E180*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech E180] +inherits = *E180*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech E180 (0.5 mm nozzle)] +inherits = *E180*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech E180 (0.6 mm nozzle)] +inherits = *E180*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech E180 (0.8 mm nozzle)] +inherits = *E180*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech MeDucer (0.2 mm nozzle)] +inherits = *MeDucer*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeDucer (0.3 mm nozzle)] +inherits = *MeDucer*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeDucer] +inherits = *MeDucer*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeDucer (0.5 mm nozzle)] +inherits = *MeDucer*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeDucer (0.6 mm nozzle)] +inherits = *MeDucer*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeDucer (0.8 mm nozzle)] +inherits = *MeDucer*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech MeCreator (0.2 mm nozzle)] +inherits = *MeCreator*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator (0.3 mm nozzle)] +inherits = *MeCreator*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator] +inherits = *MeCreator*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator (0.5 mm nozzle)] +inherits = *MeCreator*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator (0.6 mm nozzle)] +inherits = *MeCreator*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator (0.8 mm nozzle)] +inherits = *MeCreator*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech MeCreator2 (0.2 mm nozzle)] +inherits = *MeCreator2*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator2 (0.3 mm nozzle)] +inherits = *MeCreator2*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator2] +inherits = *MeCreator2*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator2 (0.5 mm nozzle)] +inherits = *MeCreator2*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator2 (0.6 mm nozzle)] +inherits = *MeCreator2*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech MeCreator2 (0.8 mm nozzle)] +inherits = *MeCreator2*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech GiantArmD200 (0.2 mm nozzle)] +inherits = *GiantArmD200*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech GiantArmD200 (0.3 mm nozzle)] +inherits = *GiantArmD200*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech GiantArmD200] +inherits = *GiantArmD200*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech GiantArmD200 (0.5 mm nozzle)] +inherits = *GiantArmD200*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech GiantArmD200 (0.6 mm nozzle)] +inherits = *GiantArmD200*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech GiantArmD200 (0.8 mm nozzle)] +inherits = *GiantArmD200*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech I3ProB (0.2 mm nozzle)] +inherits = *I3ProB*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProB (0.3 mm nozzle)] +inherits = *I3ProB*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProB] +inherits = *I3ProB*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProB (0.5 mm nozzle)] +inherits = *I3ProB*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProB (0.6 mm nozzle)] +inherits = *I3ProB*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProB (0.8 mm nozzle)] +inherits = *I3ProB*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech I3ProW (0.2 mm nozzle)] +inherits = *I3ProW*; *0.2nozzle* +default_print_profile = 0.08 mm SUPERDETAIL (0.2mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProW (0.3 mm nozzle)] +inherits = *I3ProW*; *0.3nozzle* +default_print_profile = 0.12 mm DETAIL (0.3mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProW] +inherits = *I3ProW*; *0.4nozzle* +default_print_profile = 0.20 mm NORMAL @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProW (0.5 mm nozzle)] +inherits = *I3ProW*; *0.5nozzle* +default_print_profile = 0.28 mm SUPERDRAFT (0.5mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProW (0.6 mm nozzle)] +inherits = *I3ProW*; *0.6nozzle* +default_print_profile = 0.36 mm CHUNKY (0.6mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech +[printer:Geeetech I3ProW (0.8 mm nozzle)] +inherits = *I3ProW*; *0.8nozzle* +default_print_profile = 0.44 mm SUPERCHUNKY (0.8mm nozzle) @Geeetech +default_filament_profile = Generic PLA @Geeetech + +[printer:Geeetech I3ProC] +inherits = *common*; *DualExtruderPrinter*; *0.4nozzle*; *Retract_1mm*; *PausePrint* +printer_model = I3ProC +bed_shape = 0x0,200x0,200x200,0x200 +max_print_height = 180 +nozzle_diameter = 0.4,0.4 +extruder_colour = #FF8000;#DB5182 +default_print_profile = 0.20 mm NORMAL @Multi-extruder +default_filament_profile = Generic PLA @Geeetech +layer_gcode = ;▩▩▩▩▩▩▩▩▩▩【I3ProC】# layer No:[layer_num] ———>Print Height:[layer_z] mm ▩▩▩▩▩▩▩▩▩▩ +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_Geeetech\nPRINTER_MODEL_I3ProC\nPRINTER_HAS_DirectDriveExtruder +######################################### +########## End ###printer presets ##### +######################################### \ No newline at end of file diff --git a/resources/profiles/Geeetech/125X130.stl b/resources/profiles/Geeetech/125X130.stl new file mode 100644 index 0000000000000000000000000000000000000000..968daa2ef76df5fae40c36dfea595cc7de21f810 GIT binary patch literal 684 zcmbV|O$x#=5QXOe9-YI(2?!pc2XG?@F5I~aUQF?1zBkF_N8`o^ZQe}#5tT@S|I + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/150x150.stl b/resources/profiles/Geeetech/150x150.stl new file mode 100644 index 0000000000000000000000000000000000000000..41f7363250e691a1a37322f1f15402cb93aabb18 GIT binary patch literal 684 zcmbtQF%H5o4D-%81ssL2h^8wXU9%MyK$16i|zBdc|PvL zt-GH0{U!Cg!}f*f{=i0v{MJK1<0LXBk<$k!IU+dn232I^uHbEiu#rXxQnA*AFfxN*t;>{Jo;Ta0>3V*NWZ_&YfYz1ENt6;_b!lNoO v$_T2o3$y24;ZgGFE>H#LP_?Q+jd^c}2j0v#Vb=YWa}uJ3DrS|1B3b_zKM{P! literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/150x150.svg b/resources/profiles/Geeetech/150x150.svg new file mode 100644 index 0000000000..ca38110040 --- /dev/null +++ b/resources/profiles/Geeetech/150x150.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/160x160.stl b/resources/profiles/Geeetech/160x160.stl new file mode 100644 index 0000000000000000000000000000000000000000..615b54f4a7ca633788692dd713eacc20381586e0 GIT binary patch literal 684 zcmbVIF%H5o49o*~L_bgo7+8zK!onkv=zxS&sW33+Dg6nkFXPUMou=)?Np3E-&*$dZ zJ?^*a(w_SE`s(_9efIV4uze${f3R^x_{brjVRUZr&K + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/180X150.stl b/resources/profiles/Geeetech/180X150.stl new file mode 100644 index 0000000000000000000000000000000000000000..740e7a5db70a5a326cf34079956525304cc8b95d GIT binary patch literal 684 zcmbV|I}XAy5JdL?93mHploUvGAd7;Ao<5{NLP7%3`xKmn9>mF*S$q9~&@fWs*-f5j z?aS$S*f-m8eI3SgyK!y5=yv_QYyQ+sDF4t!U-y^D&55j@BI;2mkA9F6K6oQoeG#Cu z{1V>dFYHrgpw^7o{~%Br!7r9KF%|cZQUdAazR9B>WD~J6BKhA_#rvvG%h@dtD}9#T zun{T42v-pv-|>*Llb5rXC#TO+g6Y_Al8AYc@W{ZOO`V*7l+#86ixSMhL)nDt*>~EO EH-o!^L;wH) literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/180x150.svg b/resources/profiles/Geeetech/180x150.svg new file mode 100644 index 0000000000..d21c613891 --- /dev/null +++ b/resources/profiles/Geeetech/180x150.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/200x200.stl b/resources/profiles/Geeetech/200x200.stl new file mode 100644 index 0000000000000000000000000000000000000000..c5dcfe68fb21c1e8d9860d7d334b200dce2b41d8 GIT binary patch literal 684 zcmbu5F%H5o3`KJQ4$%u#s^9>iOmGhtBqRnF#@r0lsmJ1dr%oE$jW4EYa>WXxPr#!#$V6J&^ zDqmp=uF87F{WiAJ{28Vg+quPqe1>nNn=1;(vnb#d{$9=B(xH3V3SRN6P{sX}6N+nDcbcFa>j@+Eh?e-rMou&3qGO-Osot5iLxysH_w*_kRHxV~VH% literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/200x200.svg b/resources/profiles/Geeetech/200x200.svg new file mode 100644 index 0000000000..44c5a5415f --- /dev/null +++ b/resources/profiles/Geeetech/200x200.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/220x220.stl b/resources/profiles/Geeetech/220x220.stl new file mode 100644 index 0000000000000000000000000000000000000000..6519746e8a829a5a39a27a8a07fc77a94639d4ae GIT binary patch literal 684 zcmbtQ!41MN4Dc??-A-X?s5JKN}*k_qVmLzii;3P)`M?S+8nz<`@+bE!}&=a`k`HctWng>qi zD@=havtDt(ovk>(z!Y;kH$0Hf@QrwLMR0hA0=&ZCtNB}W@E%)%SNtkiali1W3Pl+~ tm33kEx+^?N9^D0|z#OV}6{s=q?eM^x`6kS|pK(q?v@pf0vQebm{{^^nkWv5u literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/220x220.svg b/resources/profiles/Geeetech/220x220.svg new file mode 100644 index 0000000000..20b4b8a0ca --- /dev/null +++ b/resources/profiles/Geeetech/220x220.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/250x250.stl b/resources/profiles/Geeetech/250x250.stl new file mode 100644 index 0000000000000000000000000000000000000000..b95a5e66e13f7a3733f4eb1574a874c83bb4b5db GIT binary patch literal 684 zcmbtQF%H5o4DBRr;vpc`{oLUe!NAcVf{u+K7!EJ@`2!AXt?j(mnGG;>$*woyP`p(k+7^BWJ$H4mK3 zSC|4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/255x255.stl b/resources/profiles/Geeetech/255x255.stl new file mode 100644 index 0000000000000000000000000000000000000000..a60b4a405aa52da06614e26d5079a71c2864a723 GIT binary patch literal 684 zcmbVIF%H5o49o*~L_g34sWT`O3llFuVyT3LL>I*5pMmV+d0W;rPW#j&P2Af+{3&Q}DJ@KwTgQa7ptk z56o2$oXi)f0#|0OVtyN2aejs>#(J)MAfI3x@n#C=@N@-ufxTDtx9H&Aw*oI%Dp)Z; z_b3WM89|kHVfMVsJ#rr18LGe>sx}pmegz?<17%$lEaPD0dB#jLVY#MJ)-%cz@< literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/255x255.svg b/resources/profiles/Geeetech/255x255.svg new file mode 100644 index 0000000000..ff0373ac61 --- /dev/null +++ b/resources/profiles/Geeetech/255x255.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/300x180.stl b/resources/profiles/Geeetech/300x180.stl new file mode 100644 index 0000000000000000000000000000000000000000..ee1d4867478f78006cb970fbc5c62cad467e318a GIT binary patch literal 684 zcmbV|F%H5o3`KnaX69a?QhoMgRZ+ literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/300x180.svg b/resources/profiles/Geeetech/300x180.svg new file mode 100644 index 0000000000..4cba3065e9 --- /dev/null +++ b/resources/profiles/Geeetech/300x180.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/320x320.stl b/resources/profiles/Geeetech/320x320.stl new file mode 100644 index 0000000000000000000000000000000000000000..086d5064a61d16ebf6462c8964a59a5772a1301c GIT binary patch literal 684 zcmbu5OAf*?3`BDP4v`B~s^|gubi+Z|AR)0}!!kDmsTbpoQzs4Wj*;9&sy^Krjj z<7w!-%efo&{fmfyU>Ah+w!=Pg3L%am96y}mMB(H!Op!8og>EYa>WXxLr#!#$V6J&^ zDqmp=uF87F{WiAJ{28X0+PTGpe1>nNn=1;(vnb#d{$9=B(xH3V3SRN6P{sX}6N+nDcbcFa>j@+Eh?e-rMou&3qGO-Osot5iLxysH_xY?*9V1#9O`q literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/320x320.svg b/resources/profiles/Geeetech/320x320.svg new file mode 100644 index 0000000000..202c7c0542 --- /dev/null +++ b/resources/profiles/Geeetech/320x320.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/Geeetech/A10M_thumbnail.png b/resources/profiles/Geeetech/A10M_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..e487b34126cd65f565f9af01733a062ea431fa86 GIT binary patch literal 45048 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 BPdESo literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/A20M_thumbnail.png b/resources/profiles/Geeetech/A20M_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..ab48da911f950b5700f810d6e20c7398effa6e43 GIT binary patch literal 42458 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 F{{!;$yUqXr literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/A20T_thumbnail.png b/resources/profiles/Geeetech/A20T_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..a184f30777ec575557e102b542f3bbf04f677c29 GIT binary patch literal 57482 zcmcFqV{;}<)4gKb+1R#i+qP}n$;P&A+t$W5H@5xk{o(xy@1SOCK1_9WcXgdJbtY0l zP8<#z8yWxrz)4DoDE(WT0RSKXB>2A__P)+B06-b;rJ~`YWav)d;AC%RX=6&@;^|;Y zVCrFM1^{?$)MQ(x;&3|E{1~HY0h{%w2H$13fzayjih?$+Etgz-B}%B7GGXq+Lrh;A zFcfqDy#3UEAoyv*EgvsPGkR`|!TmX_dOKhp?}x+bMF7?eslej zJG&U8lM(jrSw1ViT{m?*IzdzN(lB{5>K}Tu`Ceaf3!P9RCT&X@eow zz8~^u6%E~Z`fhl16;oa2rX^Raxjj*y(DVzQz176BEZ0cut~j|-`p%qYe|vT3OYL;a z6JiG&1OvwBNdMdI=NiucFYrl(Rrlo;JqdFVrZqbQ6 zOiYqAP07l#1cQ2LS;d*QWkoH;xu_&n+p?u)C97p#dA8?qL;Gg?z1|`+nMSQflf8+t z{bbxOd7up92Ge*n!z|ZyW!)@~ZH&lAP0w_BSxvunG?x3Sd#bkUs@FCS1-{@&j_-JB zQI6kjlyt?e^DR}|zUylPm%j?V*Ye|J_Xq#qrV4#m>dg1beA%OgRrgev2+}-iB^vEF zXZ?XJwSa(lO~wu3NqNd*rsr=H(MZ@v3tP9_q0mX>zbHl>`{q~Q8XbK-cCj7b?ic7k zGn1UO+dl)7qV5ZMD_8VtwlGku+70sPR&u^XA0D$2Is7uuFIhiVt9`x&n3vg2V>3k$ z<2e|IJC-$n%eGx{0G=KzOV?+NDn<|reJj_M&Lf`IC&8AN8;6AXUg^_yyBHqT$2$zE zCn#NAo6e?8#+boX*&1wjeDaKZY4?9}+H%mOb3tdzxr5$B1hj0imEAST_)n_sVtedu zv8}fsT06`R!P7$bctf_f#X?4gf9!5(G)}vd)ouVRznNxpL^8RFz0qCUJPQgJY_^(a z_})er|6UR-5Doq%YSrA=6PGf^`$f4ne85 z%~H1uU}tRn8f2v;j9B1o*z6iwq7o*wtN2`=>tnODG3nUA7Ce`RMHKdZZMAArJRBm- z;aQw%3vRw?EqMb_;t*k%ny4U6sp;fPE;F0pQJo50m}PLscFjU2$nsPt;;b}QOrUoH zoBX@w=T1?qUoSYvOtq=o*k}yd)F4BmON=pRJXsc8hAB>HC%B~?z3Y*LD?smYuuEY{ zD4dNeV5vG6#{r#59R`T`7i_5g1mObr905rUv}MXngs7jo!<8w#`X*XExd!P4I=AJG ziLfkfWRXx*32~q~2IiJ51xcL`*-B&rLUs(7QK*^~^5bQK7#HB;_W~>=f3K@oE^R?i zr$=Sf9g>@24Meq4>;vZ?fEj0pc-+N$?LpwVCi5y{7!Xz|l5F511|NQJ8D9y&uOwPO z-SwL7o=9U8V1An>3Tf3(V2_Pt2CVkXZaGGt!`wj;c($et--;*;1 z^CnHDbO~QHaY|I)lRt42g6$PTY0@u(EQO9&x;SAkk@$SIh_D<{VQq~s@cdeIOSfzH zPufiJI5cjuk>!LW+~Kqc&XBaE;DjN8Gk5|F1^2)N2z3CZGaMsRGHK@>StA5n(sL6$8zqB-zTkfsSSR27kL$d|nh#>YcW5+F5!bR)l55LkkQM#lpcQYoKj^t?CqM z_E@&=>Ug7H*o;;~T3r{~qWQ}JwYRZ(U@Pz5f^UISBUSNi)>Jfyh3pGo1f)k_F%0q^ zfCsnZ5Lbpn7(bbl8Wh=E*9gfqdlD(kE(%T&c#wg($1J}~9jf$qBEuBfhm8v+~*nEABL=(PJ;B-43>^2%Fnsk~fmMK>B}829Vr5DFsK9(%$+o za3Dv?8`VOt=p@(ysCh&M5|_7;@?E9ENnL2%fx@x0YrGLr(wdv0SS`?ofB0x>hMp*x zF+(j+-Xd3k76&^}NHJ#bw`W8x^W9!3nb222LtkWE@NNF=-E%lJuUO;8JiXp6lod54 zp~|I@@P`F$cl(!xubQhOLF|t3`-^f1E(4!#jS+3MBeJuZvaMPWkV}x4d;%lI8kF7$ zsUw-L0b69`Kg0Ghs|E_W`V`G_*OCpSQd=e9^r>8oT7h{4*! zhle*#OpGh;evhL<$!8(;6UyvU5E4}&a3CU|h)gI#R1Co%DQ2Uo@tZsu*9ID@Jj z?pb@_LER_@S)qs<0b1V4;5{1(io|#b`)6XLvC~5bHEA6j@a!61lL~4+PVOw+b+WKj8gMB91VfsI~h_wAe~5K+=#k zO&TE)SlZ59^aBWg^@1{A9K{2;hQN!E26(C+k7e)kejC8<4U51Lf~Kal^p~}2NOwb4 zdaL;uV+(mOz(sH`axH;;A&D8l4+il^TdZ*0B~kYM!YtLslPnL42r&L7Lk?=}x6jo6 zW~PGRg)fpadfX8KO6QQk3K!+&gp>ydfw2Q(1)7*jlUwgK`J2?}Z-S@mQ`v2}i#tCk zO13*!H*kAv32HuIl6ia`l<;f|f0Di!6h{9%s^qGiX{an59KjW*65mpa zoo;|5Dokf;mqv^eb%?l~{?P#XLE_S)c$agC2~Er$?@yS!2$TbG??~hlSOj6Qs2gmdf0!K5ST z+^21$wgF@u2rbZM1z9kZ@SF~!XslP`5Aosa_Dj9|yIW~lqd_iNwa}ex)Wb5>2o7Mt zE{6Ivg;<(lQ`LI}kwq}vH#9q9JtF;Sdq-f`M0&=me7CHy%i(Q#!O?2CM(TT9ya&5g z#>(|^pjoqxL(}B%d_)&rR50*h2`WnjN0Ek~3WBziZjGl!C?p90F6D0{G;qTa>`^Y7 z*IwW4(u81*i0^aZc-8|f!ORHI!jOu#fZP68#zTghbAtAB>BOSl_tlF;5&)IPRb>xN zILAzqlK#8w=ol`Sp!sbcZMiZSIVk>V9O8t@pXn!K70IpUw2+4LC9E}q z!+>O`S~%z1*5^X@V&zAtGay5Dz-aGfwEyd&xnPs@Z^%LAfzI%x}C6 zwAoov62(8bOqo!14XnF?LxO4*BhxXTUZxu)n#h*T3C8dK4Wt6JV7iItNx^dV z0sa(sDL@pP%^JBW%yk04MS_cmP^z&~VWg6=EaTO>&C3%%mzWgI)no0%UX%8A+xATv zb}m^tu96nd(lHVU1Cl>=zfD zq8I!sxuEgoxHoAY9ZiXGQMulqZ(NBbG}PUq*4gP$Nc;xyjt}c*pro@G4!cn)G=iCh zjMQ*?A-DU}fDgjV3cDSZ84x+IDvtb#Voq12rer3NO!ZB;CihM(ys>F~Kx0gA z!qE4HrS8Y|`+-uIaT*;gw9*IFyW$aA@L|Rj^C1&oVF;S^F4k6De;9a9w3YOxhpdA|av8%Rc6O5w=_OQ~qmN6f zpM^vyd>zbBQrV2ipNkB#UVvAt2MaF~kJmW1kA_^vh7#f9PM-0IFx~JT?k{(ui4anY z((<@Zks>#QFCNBC;Y0)|XKX7^w2>S$avFkdr)EjTIxMJ|{#qP*$F2@8$7Q>H92Q;= zGnr(CFJ^L^E)ZhyG#DG0X0R|Eo4by?3S~7&%}s~c;&H-dI}wBmPV@#mPsHG2$Y5n_ zVDL`(=3$8w810SQ{^3PbNEcUv7LHFZVD<9qO4ujRL1i7M^~`q0rB>=BV@Z?^`;L}5WBR^Z4JIunpobYpmIvsYr^nXeEl zr_F-ehbL^N0!9G~eG!)lauru-D0-^v-|Hx|+HepMxycWNdc1DN-T+Sz6N3zqQ=F%) z02MewU*66aSpt%{5e%;UYMfJOtXwEsqk@cm6@IUP%&KNk^&oCWwTqq`n-Sg!6|kAzE)0=Z z0dkC@oP;<0xO`{Z@#a$BpqeNCrKluCLy^j9-%@;%qj1(PSqK@#U+j=L6zODAc}30+ zT@W4gB>a(%xO?kir-0B394Nq#*2Gq?-x}ot+O@~HGD9P;f@3FR>Q+r5k*DbqG_FDf zE3z~W#Faj7P-+L-PM-IW3j02bycz*G&?=PY#^n%a$5SLGm>j^tu`EV{G}VDh4XiRx z>3?I{*|$h)+0$W<;3Q>%kNuq?h|QUi93aA`q5uYyAtg|P0Gks)Wp*_fn2w@|s}eP0 zQw2WQwS|5Y$s`#wZqwr2tiBdd<+ zKY-&uz(V}Vu#Vyw+}nmY|EoWzxll?`T9j2Ik!5t|dl7!-390~WGFT05xnKLCH=QUQ z%}w~vus!FD)VD-#zAat#gi3-zvcM!Esr8sN~?NDDs#F^FpSXg`k8eBS2= z{i_naK3P4UvR4{0Nc?xRos~1z2BG%VRW@jrgU03tu880P)$O7wk`yz!5v35BW{TU9 z8NtPco3raQr5`R{)(Kh~Hw+pjuIdg|r`NMx z-1Ex(%c%ynn{mBuLePcB4d^#MvHGyPC{Y2&Aag&w@Ek;c{)Jt?(*|y}HB4{_sW*el z!fEij5T9$PXLLSUbO7VPm~rfc55=!v+=hsr3*{t-gsPvu4NP2uGM%{=Qh29-Q^q9n zp4{Ri{BJFU8wBCebqkQ!YER1})s8w;VEl}NTnMS?QRn$wuk|(*pm==F?LN?a11~%l z>fW(}?I6X`va_b)B%YHeAbF@#^Q{pio0$2Fv^G|Fz7XS|${xWRKSg^uhj0E80ma(9 zhq1TSRH9oCG5Af+VT4k~_}4GnZ~Cvcy^I&pL^!;$7drVX<@+e_B>`TN0QKYK-!1qH z{v{<;tNSVv=)Zo?3-X3W3jy^JmbYQ!QGY| z$8(+-EJa#Lo69tg|CSXX90#!zY;cr!2C|WlfV2!Vni5lYgdO(>Z)Os1$3kX6viT&F zvjxfPka!JzFXe4$#!iq$B{aDjk7cw-W>4KM8FqAM9#I#|pl#n!CH^ViSgS0y~r3>B!$py&*Qpsl$H zl5bcPRc;{jDMJ!;LPCWYkebqNo(e=#NI3>h=H;3Syi~~1 z2m+FMZZ~Z2|{DnEKeH7rL$#nUu*v?aYkC? zu*5s+7=OnrHBw5LN9q@?{>%HmuF2U;l`_u8)YwCRx$kHnme zx3oqo(1MgZ{NnM=;`bEB-4LKk@`7;p-?F4%ihkcUpK@f!%I)SY=s@f7yC8~#V^LK3 zE$SiWv%gbxsP&yj$kz&t5g3x0WMbCD+$X%m?Mhr|fzwxZd}yfkPo zQ2vHbSc)ENV=YJ-Hla!T*i-u|%)bjU+@m!YCB7>iSpcAIphkRR&Ba07JI?+31B?_V zWRx1AaJ3nl!Y&ZFAf(@uDBgAN22{cAaSVia7{WY3^a^{DW{NARzdQ?P2vUYF1E)r& zvrvYvLh%iwvvd9|=#=TUM~Fd$2g(U~F`+`BrM_~VP}w$)k$xf5Mo0$!8=*?}yzD`x zWkWnWEz13z>V#$#5l^SAr^A8xo~!`>g~X9_#vk1a-(7Ve%n|12ztd;wq}fVhCY z9Uj`%g9=i6C23eRae1X1W&)20(0HSYktuB;Z$1@@)UbSly@52Ug@)kK2{M`l>)HjwgpKH>Tz4d zb2%anY(zyCj-T*-KDf%=knGi+v8QByi7X?lyf6mSq^K{C3{YbB@s`z$L?!6{pt(a5 z&pjI7jQtIp5un3h3^ftXTR=R5UfU-Hf6do+UOLaV2_5W!#)5#PVF=Q5xhAu-Z^^qq z+4i8m$}`9jqExlgPBoIgBZ3Ay1V;eez~7QPg2TCMoPSuEQB1Tnr$VPaQZ(KoM$*z- zR!z~nko4dZM)Aq6uF*M@!R34e?U5fUlv-#YG4IMVz5tryKJdv)tGpa(Ao%Ob^C|!& z&g$dAV65i;4?MMv$2Kf`g-WjtWu5*)J*e_Wd388qncc)B*>w%|$|`b^6{|cM5AIA*F;DSi-Yhnj5Ks83sOU(kxR#^=!%=Ok*8*3eI25%}8SLg<;lq z*Z2fJCs0vax*%00R^!zaVqI3%W?rQN(5FlTXc?nq!Pl4a{)OzgEqn$f04Dg=ez1m- zi_7!!j`sVx3Ii0LbaW7<9@`j3G9HQMJ4j;td;gYCF*D_r3RbVaQgHzuE3t4i4`z7)f<_rmV=6N*E*|V%S6Pugu}O)bk0b(#I>o- zvKLye1w;@bWjfi3KIe13nz@3%upDAoW|6fDM)&mUUFBDxnUNK-#7vB2OhZQn&T87T z;g(Gch?(*eT@cQQg7~4??-wGp22SyIVqrx;$5#Lv(8quyZD2{a84qhD|^^Q)o2=)fzhSRRk2 zRZK;Jx~~j)sz210ZivxNstA$ih!F$>?0bk$mujk||D14CGL>i{nSWtiOb5B_QVMCTBJvp!*RBfx)V( zBN7z4uu!%1pgxkG0K7PwgUS-i&E&|-i8J*;$m;sekv!m42db+C_}=kT0F_@&#JPjK z>S}o$YJ!S?@RLZO7gQ)Kx&4T&p$iIi>%!cOSU8P0GqMU&1FLzj29waO9Qg5a_loGxg6~5vz%4 z;miZ<6|9O^JME?I6Z%GKSvIVouG%ESNWk$EgbJ0Vvfe}Zn!9Y2FmD8F1?B)u$zTHY zuR;AQW0qf)=7Vdv%6cCpCJW^>ENfLoa*}V}!SBJ!e4A)3wr$;j;d~;n1l^rj(ph!I zPz?1hAp+gt6YiE`GTT9lx0b%BGqUJ?R?P(l8VB|Oyxg!?uvU}hrB;DCA2L=yCZH+; z-H0K#a2%cC<72El;4;qSCC}}fb0u9?_^TT9oY=X*a2AZ#>7zplAL+r$xn)L#-sAPa z*BTn72TH;4^WRiP2Sb0=WOufhWpfH3Io-Z?1xXq0Z!=ds1Li$skPv~Cz z(E^K50P^saS+c|p8v)Ee{d=b9GUb zY9Ynz7P3D)9;!O*XGJ7#;?od2vkddPd$ZzO?uzQXA>>2nKg6ZBjP@}4>_<7Q17DNN z!7O(p%=dEiZaskX%%$5d{lk7GPsX}Zi6f3!wIfwdh8wM@jNaiYV2adm zpkvgB;`YQ18gR&SBuhTY)cX)O;SdL7UkL&QxkqC0m0QFYpx&mVzE5 zLfWW@rALc@bN~$%T9ipEQ}cxKnmiz2I8n^ zgP02E5M00X(A^TZ71<~rQG~l_dfv(GV>V{tPO#=03(Q}P<+(?2-RycK>fj||Y92uE z%nD4Gs-6ZB8L?KUCWSmv$3#OY;Ujul3#!|~8MavTnUt&DzF4<+%leltHu= zROap3j%m})a}=Ow$N*X+vKMl*CjaJefsnH#mXUyaI)IfH_uW;DxfBbUeU~$UO&I6X z?)ffotJfTn3?+ZYKaR6i3}yGc@^0{v<%KAP=tTCxvJM$WUt$+4U9&q)eI?C(F--ZJcKJI>zWOIn4P$Mzwoc%|@X&JRSl+N=Y- z%UWH@r5Fw`XHMd4RfHxhe0YMxLyhsd5NR3U?gvlWQcpP6!yW-6c?I}+2$bgjy>A}vYZImzjgL|GWkp7yq@;sW(P`o}c7yuP8!N5VUOOg0P(0fwj}@$f(BuKO%Aa}g0a~uk9s%Hk z6(S~8a;9uKlFAGDEaSR3R&&gn{q3bwsaP`A(7=8Y8{?2@ylivJVy8ev`whczQB->? zkG}Iu)gP2wT+gt-7dyJ^KqI(kz<*_zy+H9_*&0P_8R~Sv3YX!CN~$z1vZh9f*3I?5ZH|f`&HNLJhxMQDbq2~cpZ7n34WFcMnj0T;j;1eFyVJlq&IqmVqq^Y zg4_36>Iuf2%4W-PtHXNdu+|&u8;|pe70w~Ti=4aaLK#VMA693clQmRtOh}ZW>SC}H zAFXK+>w~m{>}Qbkh`^D9Yh`5{xE3|dR|FMvCaWrE^C`)oA=5@aRx~!xBpf_LjdIwA zoQD}9r>mJK6>PjGm1_*(V7=8$tc8gjvOZZ_-wIYwi1uh4)mLtxHEK%5|^vqRiZGv%nxE*2FxL()7hFOwY+ytdsa z!4rZY4N9Zvu_*yISx*8N$-MGT{l7T$Vu2}L+d-#YVms9xgX}_S7oIhJ$7oavFx+t{m+2vWff@ut6`U~n z5-!c#&fXfPGb~iSJyV*&f)%(=o2v2ycSoyQ92zrBFh3G%h*Y0yWF)&zlNyBtP&ix0`pA)xSmW$!D0=70SFT&yFNsPBQV7~d zfi$Bbx{K__28EKRlnd5ZRZ#HN;%5R93jdfm6{KCfh#N3vT_r^NuVo>N)fXSjnAS^nj3{wdWpfH^H^Ot(&QR8C>rylxvGuKJ>__$HiCZ*ysW4)Io6@inn_h8K(&7A`bLzL0!fwzrT_ z8zoH3Go9@uLPyxMnhx-FX>Prq%cc8S>u>9w-Y8SX%`cdG=Ayev&GP1x?q*$Ejh|67 zBBz+%6!%-V@g@cM8#=igU5jdOCu-Mq*QQ+0#s0okmgO#~k(vu~SX|oS@XL+SF(TTY zIY!j=5uZuJlWjPs`rgNV>3i-<9v5Xu-3!rq8yS61F{j?d85Wl)&DxaNR(223^6~>hUg0_EV6>s2ay1=u}FWH7Dx*9GW$!tXh0>-%s94kQ- zY#ql9LVBnO+|S1NEnh5qnvh-xFBvRU`QHL>?zH<$Vx#R*qJ-pqMUSH<&jmL*kp#;g z4uJ%WJKNX@V0c`bgpovSy-fS*Q)CIibrSi-yDA_pQ27sb{N0XvZCm_ZFIT^oIrn}h z)OAmphW>uTj4|dpeRy_E{L^QKSPBa(ND2%8pCt325Hs61fmdQk0B1yBxkQN?-VG6H zLLrAHVz)@80TNwGyFe8p>4KcaQbI`w2W&Mc82`5_1ctdTt`3;sEy(cvgyg)a)Th3Z z1=8VwBmd5}_f`)`h*t)s*cfJhd1-Eh*szP4>SIsgFX3BbXl7*QW(_Asu+=+P1O)w? zL7u6vt-K=gEN09-q{x%>(yZZM!;4v^qn>#j<55bfuh||dWiZJ6PP%TdG0p>Kf#%>( zDn_{+5;W)=8g|BNOK1m@2MTJ6l=>3f*~i@@nw09A54oSAf!UpjM_hjdMH)gd4-g59 zqL3#UkV;iaM+AbNiRr$9Hu1^RWNMKyInfmYfhV4We+F*sVm^o4lTaf7IrOPdjIgh6 zfnt9ed*f)U9DzOZ0;yY$>y`r7NvweJ^D?>+av zqI)Sp9=CzNSe^LxsY{+&QMNN73(05B;3O&~yKHYNZ-0FV?BRPorj>~T*w5qEw0src39 zUFz*5m-SHVG^4qOi3$j=hXV#>8yM994VGZiczy`_+Sn6$gwY^i0ESTza7Tcz4Il*|K}ty0ZQMkeGGsdKfGLRsuAMr%%R4&W zaP9pbvg-J=8`^Hx9M^qcc2=P{QcdZi{CkM-{2Av=G0Bv~F4r1@OH0YB%F5CRAjgjz zw;WG$2o3N@#ZEm>3&LY}nk|`Q4-GK;{PZ5Af`+i%UvhbG zY%DERf4Mj?OD0oTbQDWy}f?#AK{g=ye!S}xw(9q z+FF+OH~p?jIKE4YTkgAGmz!PThjIK!n{t4;m6gg zO0cvV{rAUHoFA7>mHv4WBpxp*HzbfgH8A4m^`qOJw%XFh!XS#MN)%`bO2AP%bkam; zjZPy{=yW>6cVqa!O}mya)M|7z>%!^N|8rQYt!J2_0>x2AHjcTKRrcALBw%!Ol=JN< z2|#h=Y_tB!;=bee%lrA-bi1nBxK4wDa+qE^us4U;dvln=+u7CW zabFQ*<7GxHxQ8M+AwxHoSR(y&W|R@mdOiFq^4nCKf-)mByWbHPd4lB4C%1n!tE8qS zG|S%+CeCgRAkd*>HoL>y+^h!L#NmZ^oF2Tiuz;;q`mfA`Z?;k`gi}NbPs99a}Ext_|Z`@Kw}3^m)q6f{cya4 zF#PZMzyZN)|J#Ae%Kgsk{SCM)y^d(hjmO7Fq);S9%=wKCIiiGO1qudE&HTs1;ZJl9%9*Qt%U;SEt6OsCZDN03uZ z8|-KC$jHc=L)Z}Hgt2Lkuw)VJR74L3R;ted2WZMHEGZsUj1RXCDCR+1b&qdJ?7Z2o?%bEndCh>dy*N z%eF?CxVWY^HqpTl;cs1iKYi`BL*)EVl>ZWCyqGxx+?U6M3ClXS-~^NRdF}9^VGQp^ zqt}Ns)zVP2Gz=b9glW(fMKwpUz{1*^G{>^As0e0AK>D_UthV#K@?R|9(n`{}zLy?d z+$;u!{sq{06j-tB9y3f3@f9@+%w|diK&@6=7*DT2gGPDu5dO5)p;PNS5EL3>7-Fgk zsp2Dard+5%ktjj(x(C4z*-!8H4UF2p=TX%DP z-EfG-RH7se_O1b*kt#)lYA}kjKp%o#JzbdSgq~ZH+!zu;PMa!5#rIeL=Y4m?7585f zC_*PEZlnN(1j-Zb&n<1~yb;lC4zj=!VdW?5Mde=8^?tY1p>=h2DJrS0syvhpB8G|4 zDHxhcf*GWPx9#}+Uf$f6MFhWV3KTJf477w6AOhux{e5Bexk{e~Bx&!?j=<;9x4gWL zB~da8W>kd;4vht*ouXt~A^^!qYye6q5MY@Ok-PIM;%+RAz1kXKg6W(uKpEo(8+Unv zlJ_cYGj&9*|3+054&UfA;zWc+^sh?0Jrv>Z^t1o7Y+LD^6Af4aZ4~wH237$$#D}q^ zj7uC?u@CAoGX2lO+}t>dJkJiWOrI4NSBe$Kaj^gUzCDdzce+!BN(v5rdhGe4^q{?$l4LVvH2GWx*y7~OH@HAb8QOF-0#qrgL5krQkbi!MZhyRI-}lC=z4#YQ zP1Z{V3KP^3nF0n_;@&b3#U~=|umaM2C1jOq5Evx-zNk9Z1SO)9VHUVzl_MukEp6?{ z;)BGgT~G>~vE^C%lu)H@=uT>5>@dgJ^6^0rmkLziuP>np5596cA>z~-B}u1snj4=J zZXn3P2zT8ly^T#R!kz4tjzlG;jMvE~?802;!!>RPSx1j8M@lH>623{Yp?ZPQsZdF<(#k-%b4@lu=kr=$rApbBXT~qFF7=S zbRZ?wR9P6};vJQyUTsxYED;}B)IiJAv}zlk{&Jh@N|LJWrsODVKHnI;#qwY3g2h%Z zRDi{$Rml>4vClE8-n4UGOV0qyQ)^!RM5o6H(%BQKBqmeleuoCj*9 zm0l4sR3Fo7GNOsX4LH@3ETs)bA{KG#0{$e|E_pF%L&)N}V6Id_P?3Z|re>44 zc~M_}U=s?YumFkt=*;(`a*5@Qhfu|CLlN5|bQn(@<``4x#M)piK}>ypPjF3k^RVl8;K%>tAEE+^(-eDD69J zL9;uTrEsV^$COd3o?W0nkGaJ>!}E}MwdwY0vRtVOi*Qq>Kw*Rpesy)l z!oq?qMwn`v_~&m%I;L>JcyX46y)`i;h|?R6-uhx!7ZEl!muq!g)vJw~)P6f%g$f7( zqij{_Do~gE_212(Z(F+FS0cKuOQu|}b4e~PE+ip?O!N_@1f_<2_GH4!tn$J7=?#+< zZ$RiU6D^Z0mds-1;>$7(BVCArlT%{uwcT~+huyWNKfeDfg!11E~lQ6H}*b8*+vZ!h~POn zxc^XY?RM87_f30~@p5HKonDc{NEF)n-hi+KDd$%-v!(TNbf@tcJlQC@1PO9-50i8% z&EFsxdO!&#pGQ3IW@~~JYrWZ(*1rZ7R4*qU9fJ;wsO3drcpAgVJM=ot0Sq}Pz--

tz+?!ZmbnN_~2EwFq9J(jr@Qu1cvYicFW2gQ3vwq)o?RWhC z5+`s6sY$hQ>pVS zJCYLPaaZiPzA!Bc3c)^b=Cvy)k;iqa(?OCDTSLr5@vg0I@{Phwua;T>@EF+|4}2zf_o2n?BA#X z{5~I>oE{D#XJ?j$6e5%(i6heO_uKYBs3&>;cGgS@h*Aj=@`Wzlj+p|GB_>VD3rw&@ zt~WcrxIZ`CyKnckIoymP`5N#RGHc1wq&SL&fNT6XXc-W{GYmySizvd$)#5{V%5nsE1K=6;I7v+y@yRQHK z`_x%bRtAAprN_*?=;G$u;C7`ILcn#sW?bg?;QBaH)AxCtmbcrTK@oN9i;wKK>`I>^ zL;ki*#He@SNi^Zf-XC{m&FkD;XMuZU=Q zQ9(e2kF%KG`trLCtH4%4mXQ3$pkL9!mNp6X(k$&e`2YbND`lX_b4B{UpQ{62PsQuZ z_6tQHU!GL&9x5s%xw^PAGBbT91{7*9%3u6%<&9B?%JJ|kgS1BEutQqGtmbNf%2#7U z(1V;zDw-=4z2NhDUDfKSmsuCU3{C`&3>TR=>pm4_Mdb3Yl4sPYg94+kZRtALb+EdJL&dv&IYKovO zfzwOZU!6u}Nszx%^7@`z>;Vpc%J}~*Eum7Y*DjrBmuLGSWw@Zo{-O0aPQ$4UvfXTP zWr@x-K^LcYw6M1~{(64`{A2CMEbQzJPRCL-i-kJRQsEyF9Xh!-Y|{RHGx#Eb zwwlW>G-EAD!2h78>zseNE^3Ahid5y}RK^YgWG2w}@ow*c;>C)?2d=x**VAf~(Xo`w zVzlzS4bEmsM@6I!-IQ(H&fu$|#}%yN2~I`-e5qnEmGNQ6H)QOe@P9rA7a}b8f-O;L zaxwd}-r`YG@8RRMA4rblP6YecFA7v>RvY%6;S!~Ul@&KGtt^l8j6WiZ<8yO} zBSwr5PGs(f%JNR1P~`VxH@@se#)m$i#`r~LT@X{v&3N>n8@v_uw&7=Ily28sNaS#R zM~iN$HOg`7)T$4Cvu-ais3CQvVb4?pT=}|FVU{YvaA;0y?~0;7$U@yFVRkk)EIMN& z4?Je2Wt1sX5ttyg1|6Gi_9uD0?`Z#Mbrt8;#-tp4Yi$_ebRm@a;48&S>k^ zrbed;W0$*ml}Cp{;rXPUjl{y%Qguvc8dZU8(tAMhxn0d92^{%KP+BDswbvCxbG}Aj z6Ll_Ipg^S8P(fHnAxWua&ygf14i5A`^2qqQ7yROQepbdjw;PTj@{h2~%OivtGBNQ) zUu@`u?cA2K_od{0zK*`&x_?IgQm@nMIB~#d%#p;P>ppe0pFTEIl9l}<`>#$4dLvFG zn`#N`Zf{eLHDFwCceU9H>NFV`7zD)5T$dpp{A7FYcp_{$&+3M=)W82cDXf>6C7yyWAHzk&VfD7_KWsulQg#7*tXx; zb{b9C*jAG!6Weaw*tVTCwryMI`JZ#0PcU=cb7SwderwNc(V^3nz^nYy`s{5yZ)={D zdZr{6k*+_LRb0F=7Z`bmlQQ@Hg?jFd&Lm%1*cTJbY~+EuQ+Rpe3J@AbB;9=|f_Iyw z%qb8~&+)-N`#B#2eD`}8TzYQLW+Cst#*!H$ei=dt^#2C51{A;b=3*L;t6qdj1m@PO zHxmfr<*TdhJSlUU`B`k`hrr7!!IPyX|LX`tW#Q%zVZZ!S6bn6~6EuQ=JmUEBqftls zkWvX%f|tC-XcZb%Kgxx`*7YBbj9SJSr@RI*jCeOmVg^BUuiMZN#hET|!WTrubus;> zFlZ_H-?bP%x6DLyqvF(ORS92sWRy|UXsTQu9dk+Bc+FCt%OAfXv!C>lH%)Z zC<-x8SmuU!$Ns?!5MfEp)0DGg*AuiTQlo*9Y1kBYv9f{+tT(@Sv=}en$t_P2g^eW3 zc2Xz853zM#v88%usnQ+7sN`GYkyu-f`url7Y*2?JLe~AQbNZP_)(V-4}#*!dqnLp(=x20kdEcD-+dT033CnBRG=g=r=HJa2<{-~bF zZyjEr!hL5BdfJ>((1QO`1k!s)$8CZ0fYSb!n7H$GjN@XvNxTTJcqUX9ohj8(^*=^w zrGBtc)-S%m>UA_0cv?833!U|KK6;6{0v959)vz8cshL=oe$rV~yh3eQJ)|{A(|dFE zN7}+lWm!g5*#`PTLZ&q#cMJB>#Tm?lcXKYs3*y*QSDX z^rym+3QiWP(;sQ+N?@z7;22?18^~o+sQ&Z5R@eW}vqPgCQhyIkpPtm|KQf^Wdld1r812{Z*M$E++Ja*_wp?tQrj zJUz`q9HyewuUrY1u@{Z|0eN)|i%KFLjWV6dFbPaiIMT1A{eMw+ut~)+{z2HlbRx=& z$DO^9K>ZLc(>%Fl?j5!)oa@TlCE9>I`}Puqx@j66msqNaL#v5o=CfmUUV}cCYXGqe zcdu)FRGogNV~?dpN+hVF@(u;-xdh!EgPMR7j7t9tDwYM&@q2h)(r463T6oIa<_WH6 zoT`-+!}TUk8IBYjDK zJVPX(mSs`}5*o{p4D2?rMBT)Nb84!ihFTch(5Nz;jAn`IvVst25ZGV1A&6?cuJ1Da z3?lJu&|VQrtF4oITxT35MmP{53k}rhLJ;X)w|`ls{k6hjhX&KKoPdb$fmtDX7H0#Z zq27g&7f+o2Gc@G9OlB?>|6vBG1r!_4?^K9}UTcjw=Ls5EHLCE)sSZGcQ#B}#8pv}Q zXW@fUG36-VV4ao;MKFzjd;>#_v4!@A>gCE;?qNI$foXSMCaZ|q6mA1qBI9LC6a2BZ zQ5F1f8|6wW!zh>2L_SOSLdFkQ9n7{7L|2>Xs$w-+<@80jFM?g1u+m^iwwEDk8Xw zM0omn6f;~af|gEkI|*;D`WzWe*?n2PUw4 z>OBPW-IzFfXhQe3YtuS*c_l?HXNo4fP014VKmLD678Pce{&fTG9}U*nn%}E! z6po(9cJ<}!d-U%3xCS`dw4l%l6HS7YEuOQP^Fs<&pJfBZhiKiwR3!S72;BMca>?wq zilt?PM=WHNN(w!;H&et;S7(FJ`21Lp*Z|iFCg8Hm9-c)cg6+($t9I=GY2m;x~Yy}h6Ty772bXW^xEmUL=o7Y zz+7ldIf+q9lrMYm&5A6M4S4}QkPUyxOZF|3O*=n`>9#W>XJ3e1_?K5uMXXRG; zEVeO!j6?}{nk~;zax~Q&^CO2K6Bkrf;n2?M`mNR5s3Ju@WlL>^K#BZ8a9u14 zWq}RrZ8o(VzmlCG8X7H%LwlU1&WaOeX8Y+qwhEi$1^)E0BA1)wNy?3OLl1*GC#u-1 z<25%omo8>6*K3FubR1BEc5!j}H#@7ql|jzWF6J!9-eQwYo$c`zF#&5V`D&w1@o?Sn znfkUA#m5N4xkfBaq+w1A^LW9N4c-De4Gs!~iw^z8pd`{vCpEd`SEliRM75VG4P$J zlg-F~{mzG}u}yh+aGO9Z8aX&@oDt^fHz6QSOWRNC+VlCFPuFM4TUsvrvleh)?3lx?flrjDqO zuAn!=cZT0T61gkc5VCV)jDCHtNG*~{m5t9yB`bs4cZ!=9Ga=;T=uOi40F205*Hf;W z7Q7EYUAijldPVPheFX6%kEK-niDd>_?QqpVKo)h;=QFQmXw-XArFGM3}H3Yz~QJ228WP8yza@!E3>s=;+B+KK@m>oyjlRmkD+@{q+pM z<5*#PPKYmf=eSiTm6;nOyd89!Pvfx~7>ocbc0PYAF!9%pOr%D8#(N%fzIRJC&~Ra0 zF`q@eqNKWXdj_wL(2j@Yk0Rgqc` z$H&J9YtEDAr;Utfn@ur3c3|%I?Wl77wshMcP1VNxNx(iz5cufF0KD{FPoYi{qjV~a znZxn#J(S>{IwT|kj3>u0H@pXmVXtk{g|NPcUA@%{;?lJ8vlOsj;addw8|}n!0}qO* z-pi9^TGXlHqz5G!fBXkGNImFCbeJHOnA`OcWgqVU7UJIw^yJ5R$qSl!ETvY^otJ<% z*1OVRUBf^R-lRwdY4o_!Qu-~IS)yyCQoE&m1K9|MU`3itN*^5@Bxk<{?ahS2;fKrk zQIItv{KTfpK6F0%M>;9^%24_FaSst0gLrE}@_|b7xo4s6KBqE&`FzpkACh6;8GMke zIRVQGSuedrCMIMdbHU3Yp(RIeYg<7jRZX>KALJyBmqHbN)fdVVACzl&UQtPJB;g1X z3`gw!rUL&=7!?&Y&&Qxjr#DonJUqLwpvbpA+#^P=oosu))>7v=ohLC{#UlosS)9nO z&(|)0yX`>evG@|xq%?_&6f70YIB5!(Bcp;g8OzW~C_Lo{*(VhU)d5M+L=E~kQozLT z_mxaFL4R2eA=X`M@_{4xq3fW40ZK2gWpG)yknr~A4|WQJx#)@khMxUCI51ZfI;Kz# zXMs&k&-{~LmXZ8`tyyUxq2!KIRB_sWT&aVmGqsCdD2;-=g*moX_pu=i{b6TULP%!^ zE__EJrtEl}s+;4)t3s&I_CPCmd+Oa#REd}GALTVIATkl7|gvL#ExSS_Ge z3%zZ}_;`AG9gG|t6tx{D24S~)_@F+mw2;v=-is1ai=ciJsNDvQ7Jf~WPuI2R(;e$L zNH$kRqJo9l6bgKN{A$LCG@E3nmdFh0c=_fP zojgn!6yhCW|2r{&hXHh-8hDlCFMnh3yUx(WNmVd4O*rZB`c!byzWJST1{D>JXLPy0 zqjb6~92ZMK{)X)0Jm~y*-P{xq6jZQR5(YM&fWv0T9SWi`J{K6Ym5QzQ31_;x=yu-VR0ceCx1G$dE5`SwHm2h9U9!)nI*F zZcvvT76#`83f*nqyXEx*xC@`%jLm)yc|z_UBKOT0+YArC|8SuI=`c>7OPOYJt5pUd zV;U_Jq^WeeKI{Mnh4*+*?WeUZ|7a;caIAl~3&81*z;Mdv(e%?N4mrDcrF*Zh*ogF^c5sTMgIi_tBl8*FZZadTYbk6$5 zdShHFkovg^IzdzedTTH0lR=t~kkoHgD3MT0U4Rr}Q?Puv%sBvXnc?^6i7s5<$F|K5 zzljys!}sTq&$Cdophp+?+kT7~b|InY`0#@TO~S>2dIs5jbee&=ISRmQnNPN-S$CEg z7^*kZm8M+o^6zpBrkAj=fH{^2tE+nBpb+5$e8h!*SGH4&yh&@^VUG94+rR{Oiu=Xd zeZE8l_D7GNGB4sR*_Gf;@K;sZ+GR`AwTFrlS~03w`4+vRWER7OnXbT3OC|gwOO;_9 z*uX8bp_=xekq0N7Wz0fqz|&sq zv+T5|yRVgvk*XPzFNF{-M&3rFqs z-6+yj2>{^``qAl^y;{3p?*G2%kEFzNUEtmMy8h`9(@$n_{Xj23OWC5A{NDGf)8fR5 zfWsJ0gb-gcB4b{wv(B+m%YuY3q_EXmnJlRiba*;Tz5FlKY#Bo(QdhSco-G|hv@)DxIJL;^Wu`vzHKMG2|IjX(`%&~t%)*}Y`vshk4}v)3FrlW zowfqC-;U@0%g%^~y4;+^{ydHolt^c6en);*Zf-7ED=1fqXFF);f7YVmC&cV*0>C{v zjI$2qVfvhAY#L8(bd>8iMFY~k?&=D#y|z;G7tw=-Jg24=*o&!Xk^o7#;a{p9Mamf3 zHz5$Fr4L`_jy-GwO?>+F@9#`CWx2wuwJz=@%_i1bQry;>Rk^HLLZ@{(?|RRjuf)>r zGZ9a(_MUP(>DHB?#maRG3>lz054g0JQbuLr_%jQ6q*3E_l9GK-c3mosq3-iql z!L#+c2r=?LfUe>&1Nx=N=#zs#jTNg>@=8i*VA4X>u&`^#cGWa>I*A%}HY8A*qeP)j z75ND*5afCKi5p~E2b4Y3)$$RI3tVsCFHS)Hu6Zi0r)mE>VQC95hAI=?2BpuHGe!

z1j&mE6F`efsmy+zmJ(qt=iw-GB7J1Fky^wU{HyC@2WJka^J>w&GZux!`;0Yygd*T_ zdTB|TZ+-mzv7%V}LArPrpviW5phUVi1lwp*3v1_W9w9i2P6k02mi7 zuf)hid{23cnT`iKnT~^a;&J5<0$PsC5Lpg-B^R_O6efa`1%75Fr|E)PzR*byN{g;| z1O#S_mHG^N&9MLtQ&d#6)ZyK9{3_JA8*2w}E%ErE3J*W}Qn2DuH|k$$5I@(^Fc6s6 z3}h@s#=AH_m!KWl+rt!vjpnmbSeo7lJABpixt54w(5c<4?=wHD2`eG--RmRqQ)5fo zdBRXMHFEeB!ORn53{|oea39w7hFM{23)MLlMx6!NhGS@=4)^mp#@oHnYo4zP1q8rB zvP=wQL8KXq##(e_Wt^zSDr-@vBTMRaw9(@h!L`(1VTrVA+kuDro7h|1u>*F4g#2ujMOm+VW+6BONxYtGimFluI$e1uANsSXs`iD=`#SPR^3w zhr9W_h>#4k#@F$bxT2`CIu*29wqI0^9aS~tkb;!2eKe?YE2UaW=P}Fcy)|769iYRd zWzp>d)lDFS^#W?O$l|1D7D@@&f<>g4Z&5`7^mv|W1_sRafQaTDQP}HB)GJLe#TM__ zEFS38BF+{kE*TFPS~c1fancSWl=eozPUDI0J369?5qQD%f1~zaW8>g?66Vu4n4|Hz z8KJICm`%uRabtX3bHy1;VcyQWo!T!7ajULo?+cUT{~v_mabYkn?+J zAGSsTPN}MA$;_M(mk?c+8kX#CN0NX?mkjS!!=e^Q^{^EQKdx3p|y zj66m_R4C^#UXHo2up!BC<6*1|LdaJeQILzvp!uqIF;2c2RxH-i3N%zHh*&gQkT^0s zWn=u9-QiN-RA)PO8yOSh^bw2$Fd-s*vy)fDG!qJVz=&eZ^z?KG3^<#ifm(UOv6*oz ze1Oy-MHF8zAhqJ$qDL=?U(U-IU1U+wNK$UVpJfaG%aN6GjmB6=7LH?BBAb|caaNk9 zu1UF)7mT1&>q5Kvaj>}DYKBk(#sph}(y0nn(fU{{?b$_efoChcu$C*)R6I9!v4_7% zM9H26c=C;9$Vo@k!#h8|06wB3ro^6;&i`0$OUrpY0gX&e^)h#S(bG~!Mn*#Cvuk-p zMdNfMBV%6VB1lK*hQ8DX;do_7P`rH9~kzL@GxcCNoDoq6O z)8UI+Iif3a+NVmmuMtVWKL6`wOfx!w4%*s&{Zdh33l!g^@nM){3+15IUfoiOT~y#ytF-z7xfUO4K#;)Y3aXJ>>l z&GJ7jC2(XUi=3hOx~bXO#`mT3gsyk2d(OPAtzJMYM8?l9qol-r>_VL;4>m3Rvgpcc zi!fH}XhX0%$Crqvl#ZsPULhE4ppHkqm=4a3VFt!0hv`oJn}cVSh*KO)k_BXwuS81d z!!(L`GmB8*DibHh2%1P((ermF3>j=j-E#78NCBr*E=rx+MChSQ9vV-bG4Z-L!6N^m zLc!)%$rR$#42&Zx(9T^cyGFr*mz5zn$Gn5NIH)%gi302`6-nd0Gm zLk>Wf9E^VPUo>Z($tP3FVaH7tnB0TkK)e64va$vyGPvt3rik$gQ~`wmB@yu9pC;Wu zvfMwW`2li#Cz}7_Pg7M)j%!M0*XK-$z{rD!7Dtv+>S=3o038mCx)} zi0@dZfEVmlYXZrF$oX46p6zs%c$lZFB0d6lfXTV<-;gct$Wv%!pGv;6RMubJh1##` zm>Tq7B$ECLW9~bpU1SsM4OL)MAin)aP!TN3+59&znc)5!x%aPV{5;YS0+B3M3HCr~ zWp~4xZm<%REG$qpEjQVd0QP5F4N@Lu1qdJaS`UuY*fozU+cJGVhyLVuxO=B%YPyU` z(nRgq(_XyeQk4uY*ekL*M;fz4TVl@SCwHT!4jn;ub4*)gJtLctkR-0`|Hz?m?RpQm zu*9+9Tk`sb2B7TjiKiTMScjTrpG}OQ92}&k#l8U)R7s&b3;%E3O0Z|2~#9y;hJXt_HPa*~j|12=8rdEKCo#B?T z=5wg;!bNDbe}a*ko?fb1GN%Zmk`#|6R=GnKGv+=ndmOeSJ|13>ps_2-UUTRT<@ew6 z?T+NVV{>9Cz0#sP;-828Jf`!`yu7(W-kGJPzhw}flzeVBrlG1iioK|@gp*{7oD`&&Q zB#Go>`}2dGI?D$g$I#`A`?@DJiv7}mY-xIT2i*D>L|kJ0jT)%n9&!R=^ZRtpa(#D9 z_ccG5LZ`4Y;TJ~$x(2FwylBA(p6r$8xQ;e=kS^DVdLSc#e^`pJcxs^9)K3#52UOuf zTaCS4EXvQ6QASf2c8rtnIbce5*U<(N0$ARK8+QLj-V83O#Bt ztcELE!-uVUTTZwx-dt&=ZdI|?_Zs*$vt_P);H*z(wf!6|0M^@R;zYw{vnJvGaV<)8 ziwZp*ZN@Tu;HwHItIrn1R}ry%yM28I%%vvxrb_;=Kqx0}YJa)GnHpG?a3wnS1$*nE zcOdjImcqCTm@vJ!zEDqCJ*d_ebMvz0C1x)y8R9jax+=nrG6kx$qM;V_IM#{M-x1@G z0*yX_uYgM+7z8>o*e4>&8W8k$Q{az&S6ftIa3|!~w7gSDPsX#@p&4ItH|nRhF1!m+ z4cBu^FOp}6FH}MTK>UsCN%!iX*Eg6My;r>6M);dz+-N)RH@ zP9tW&+SmaA#OwX(4c0nsZb)KczX2$0VC`x5({#3O>MA1VGcxQN?&InGQi>KpM(LMZ ztZ{%mK`-JXWc+ultr{tkeE&ZvD%0zT0g*es6tV=WNlb03qov{7RC;8>-L(opSS9;V zD=LD;ZbpX&6Hk}r>1@jG<#PRe?7;-J-;o%J zPd$_Tef6%EL1M0;@D)?*lQD4LVonOZ%73NB6?6&Zv|a$pry*i@AI|E}x!EbBG3N{* zumaGS6BX-0ySw#V+&es61}*YzN&Os*>lyi0+SXyIvW2idF*Zz9S@d8TE^aY7YlPX^ zS;D0*PN5f5#H?V71Q{;dmHt*&>nZ_s1YRz#M#tBOb5my>x3e`FwzPt>vV?_3Y^Rny zFgid^Hv--rE6~;zY0q8h2??(z*VtwR^pMK0_5kBV(>PS=dRa`py!a|7@x?41mtn?g zeGVWh_)m@`el!Y5si}c!BJV~@tQy58EXgfA9q4lKzyYT`Fa6@D>qJDhYi_3%D4mCb zT7_NLQB^4>u4mQ1Yk;$m$wmOCQJRZ__x+9? zkC4##@k0N979OCfuzLMW?C^eMVc`)6?j5_{9@KBIkCzrefz99bv}ow_1^|)%RZpUo z+BL>^RaLL2b^1eGf>Q*t7U_y!Pun4ziz_RG<1WaXj}AmY;?IFF4 zULug7;V5DUK4^z3UOqZzx0MNq(ba@wv9h!47yn*BY&R}hY9CE zhYLQxZhpob2Yh^x*Tw?Cw&s8Dai8aposUWzT1?M(kB@OM3h`V|(Pz}|mWoH)^ zRs;hSCjgO~0Vki+z$Tq4Tg!YZTX3myw@Rn(;arNu_fARZp{6XKn%Lh3Ig~ytdXH!2 zCZ?djR5aXC2a?nQeWV#V6S(iq z2y_>M{!iUkM8G9qYFy`Vih|^CQH754rO) zPQDOVullME_=(-C zjVAE>pN7KV!m(uM%Z^8&bQSaW7cNnUpQ3+X!H<%qT@(L0%R-wp>gtn=4zLR75!j6C zRk&i1Z+FzfEw_0Q2JQ<1kgtm0^Aa>^Hyt5 zb~vGv@!FiGiJQYlMy5XAiauMDd1V13Xnj7yk_R(9*bsDJD3xTw8z-GtVETBGrRO-X z+Idw;zxiyv-n#jE;eOE1t_6tsv;B_xhY`C>%eri?GFIuA|XM z@A5iqK@=K?ZEP42u2xh%{GA>AY}(B=lx|vg8|#SP&*p6Rhgxmi8O@dCY#rl(25sGr z4@L=eT+^O=agNgse{N!lsLGNicDpeUE|#!?5&L-8IsPisRA2mcy?eMkGj1dZlW8(KvNS2s24riWcj2{qjF{@!i)K5cRPc4P?E&0URE~F$*hy^dDgP zEO8~9{ST*?`yt19DhwN#q93`(T}jvZvC(#^A)D#?b59vDFT!fL(2V~HBu$z_&7VMN zNYk%kqEYa<$l{84n2McTnBPygUvD#%J&QFZB`Nt97YDKdu62Ez)o8=Xs%Os!Ia&!R z3!DMfFd!0%+<}kVYK&sZsWKG4C+&OAkKV;4+$3wi%loR&vy`s4!XX19^j72Y^c94k$G}lCz&$}-{f>Ba zadP19|9CI1TH|`UfP2kWO_Z@6_uC^|%8hCafR=%Ml>rrO9i$ zkpS!$Vu3{?n{F|5E~+J?gy5hcC!3Oa-jLDfz2-jM$Cw5sny{8B5A!*-`BzU}eP2b5 zQ)mW&M!R4bx&S$eKiTh1aJV8ZKLGk|PG`eF z`o%)K3q;OJlQa4MS%6F5OZzia(cy@b+>FIKm~2m)oUtyprpy5jM)^KdKfh@34~xE{ zD4yu`Z}1J>k6CKn_z^!U)L9uJha9VICY(V!<}_S&T-eX#BrWVY(nag4C6SVq_|k=S zkrzEt1>RCKKxhCS!J z_gJ6^IB)K!7~YTC2t6iTWZNl+%NEXTM>V+1QYG+2i{+~fJwhr6nzD_oy%7e)BO)P@ z{{Hoo1D)+?_+J^E1tY^v&c`u{R=_aHTMr3-iOUM$fJGa1kVa|=KW=sT31naF*Pd=9 ztM>M@Fm5{QFaJ$yxsC2}&@o9t>-ET>j-wQp3aOr$yUA0r;OHB?t z^#ZUd$BB6@m~H~YIo;>a6XvHi3t?w`p7%}f^akN&Q=Tj8!Z!OM3Apqv&f)ZNZ* zyF_+`aCBNWBb&xeHfcKY>~X-98g^uudD<=K1(x$Lv{T*L}x z@Y$bdUQ6({Z@1WUrRBH-rRz?gM1Ouh8kIu;GUxeu6f);2 zo!fcgI@$+vc7X`8FJP@EgvSdWpUT^=jk3k!vJrptbw|o`i~cfZ?WU4n)0SrDgz-Nb z+=4^y1{H!|VXB>eC@j$DA_z=qzaIpYLLE>wfq;`$^+WW$b5IfNDktgE8mgoVBmPaA z{oBK9Y2mCp;mhkL)i;~f#So&ft#6utBapV@m(}xkR^LwR;wxRiALkMe{`b*3f86J( zg28{n5}~SXv&K(B2gu13eciQ;gsX7W&&O*T+6WPP19VhGD`v9nMbQ7&o`X&q3*auyTTZ%vRB4pjQ2+(;v$cJpaK>@>|!cxSp_oET!8 zpD3Tl8qN_2il3GDJZWEQlXzNWlS@xks%T$SkyqXAc3Q|22zgY@h3Mhr6Q;L$EC#J3 z?bdsbz@Ti8EeOMpIm7l_;{=uu@4O-NR8UYWZ`L@W0*3+W&!yk$R)v+Xl;~mz)9BVV z1h#E%C7ke_1Dc1|4Q|FqVV;k!_j~lP;^{j#yqPX2Q)f9lVM8(TxVRvj;a=pgl3bVO zUR-1B#ZHkn21@;`Gz9B3U5b58$D178g2Epk-8*l+rR|Rgt+ceO?AZzn)bn#j(;SGM zhudu*5}XGSSWdWqFyPQ?KaSX9bdLv-#Qdjpk3HS>rZ=)kvV~vl?~1-=stb<|e9O)< z+Fbyd$N0zO@0y+U(6=~grDwG@vKeyl@REDpBo1MDzm&jWtH~j`ov-xwhz)r@1+T(#O@L=kumpn#6gGGE*Jp`ohiu_;b1zB8w;8Y(bxB-EEoxLD>q>ZSARB{6sP@tIEOn zGbMx zkw}Q+NLw8U&u93j@uWN~RDS{d(vOIdC1#rkM{$m|2+&MzFLdZ5xT@GX3`-Q=?3nO} zo<}vsxXbNvos~4d#l-IJAFt2SzEKy`-xV;L77&=>Kb1-6Uqj=mJh{*QKpXMsW06CqbUCcV4S}h`h&X+4yrBnhfoCt2}Cq z#P4~JoC=J32@$GZP7I=P^>4V65lb~;DV;8*gdo)=)1f)>fV^E&kp#c7Kfm)_qyC&v zl6a5$-CX3mQ<{8R>@=ot>bTZTcETc?=2(7#g(P@XxlWi1B;M)x!OO3uK|ZaYqG@BWLRD=iR&SYd3P2+Y5^w*(C`fJl-d0de))371COR zq=w+Ksl=jZkjm;MgrpPWsu{t>pu&cKMSrgOIE_D6|Ut zw?WsgQ+szmVltjKxAf-=?7Ns)Ie}}aOH>@QCootjJ1rP~*(JM{uHv6?=p8ky_r|f&X?p2?H2IeusRmI6QAW{;HOwJOY#TmwN^r zO0_X;Nhb_7=UWC$V?qJGshO77VN=z$*KYRAtkPDJr`s5&ij@pbUHIP>tbAg)x;C`s zA|Y$F+C{;%;}Pko2JLiGYF&LSKh9?rDXDD7!C=xx_uF)qque;g6Xr|0x5+2bV=Rke zSq7L4nrZ^P^^kNR@H~cOInaO zf!mOMK*7D z$j46p+YIx&p^GcZ?bAnHGg6AF@h`*Adv_F|GqBgu#^7F2rH7=Te?sIR^VHRx`WYrl z%EX95WM|{6rclw1MXGgqdbp=8o18i*lhT^l2XBGGR|=?%Ly4z@|3HY zyR4G-m6D%AQa6(UX9_^?P#Duu@=CVo`1U+R+&lVC3^JPSu~zF=|GH-JIs1Kd2aqfJ zxy3U{84czA?eRlw2vKK~VIY$hx0$rSsj-DzUBLLKB=CUxzHTY>x~w!5jQYj;1l_iV zI=@6BU$cJX>-?O6&23;r#FBOk52@7Oum8#hjp z@n}q|ol*3U7w=LFCzSPzNCI8KPboyc7_GeM&*8wG!a_t>?vL8i^AYf&Z%AUPgwqn;dR1@r?pX;twY~os^X*yRqe_)# z4Tfc7q-~z=aNT=&*-!Owd19~3sMSX2v5XDHsVm$W6kNTguoMG-K{v9|wv9X88-xgf z_p83mZyWUsg!PHK5z47~`gztBNnEz{iLGkeP%{I1BN4y$mCZ41rH0!;xRN2Tz!lvf zo$m*cCwA|8uebR;xaf|I6#Za&NOgQd@@LzNqRp$O9Up1YDiW0A3x!H{0Jb$ud^96fgz-;5`g(CA@p7fHm~CiX07JI z(rnDuD>2#-89#sUasP7jB~^HYv%p86{dDZNb$vW4>Pc2k!2!mmuH-TUH^|Dvn;Mk& z=ezV;^LehdN&luSCH{66G34XMyZgcfOe^HKUx!HK5dX9FT62f=?H?M;* zsaI+xV)wjjT;Jcn-}W-xx0w`;)B&=dY@Kcw2BrG4HO1*rt81+D)G)BreB|zdz0s3k zxdo1Dl8`!G+UZ<@8^h6t%YLJG8&F6u+FnDt8qE<~cMFnK8!=b;P~*=>{Am3puYBQf z>rwGh)~&MJA=XGHt7%#Sy*)T7gJ&%iqb9TYMd*?awl6=}i*tO^e;7W?er;0ZvqGz5 zwCi~1^m$@;C#4%3&k-7&B(U2)N!gSYI8jc`$y2GA5$5Q<8iuv&0NbvJld1SU*>8U2 zsgCNAKa|UrNt=cmF7llaZBfwbsEoG`GX~=b(yGI&x%|t(qu+7^>Dh)hx+A-PSl#?< zG&AHE;FF|qXn7pVIY`zr7y_Sr$Eog^7xVaR@qS#!ylXKW-#o|ohu-e0weL0NkQ2Ec zjTEG15x~%f4eW?#!ZtWTi@~~`ul1w|y?VOoH$J)tC{;$qisjTNTUs6;#Fk$_rzL<= zy|N11|H^qzo5N=WKVS_Kt~9FK;+6zyNSSS!yzNYu+3y{(E7c18I4H`nH*vW|p3LO! z`~A2!kvu_gyxbaL@4M|R;Jt-e$rSX2e2H~9;#*?as|Jf$mywh zJ%ex5rE&%Q&`IlzzTjq7j=&TkFKFqx_7S6ZkoWJxWqWVgDH01z*xLK?f7h8z`ALI- zr7$xu97>DW4i2f#kF;H$z!2`p5eq>EcFpO?lp>q+1x1rVL&j<4QXh`c&EdLrZ>C{r zxE?F0FfD;2Efz5l+jE!F- zc0Yd&&InX>oF}dM+-nf>c?a|zQv26qiy{|7fkD9(>>y6DdTTr|scukak=gNNUTjLV z2tCV>*>2g!VO$BRJWwi#mYHESOaogCrJR6nAdhuM@cj>B(4`s;W?Zru#j;q79yGM3 zfCNJtl@-7GZNxY;(-styUiC%CuisJEMbLwJxOg9Y>T3L5%N%k-%Mjhj#imACGz!UG2ODiV1N-XJvlks z$FCQp-3MnSb^SB?uv=?AkPH(O`b{r=(a1}IM+H`A9*ZoT{T!IJU2{~L=`{9;k+EQn z@}&oG$vs>HNKQLAt2c4?&8$$>tWw$3+zs0>O&k12uabqGUCxA8im@ruD$y~eh(-&G z9P;;8e;hdA#+NLPXMMF&blEXbGAh_7>|~9jRI|5Yp10Ni6GhVC>ZabkZp$ozlqo!gx$39(pVA90skX38zTdxJ!3@uiEay&0cf?-FQ zW*^UR*lBNMC{@TesJ9>PK#6D%$F4JZaoveMVm1M{=yx?k0lIo}(ci>y_1fDl&DeW* zEdw_^AZIUdli=;8=?>fBq>!jiPw=huyaup^3HxvB1{*GOHGr!biWK_vmP*r;kZPlnok*OfV+9}V=@FY*=;aMBoHK{MvORg#&L61~FSoWm zk`a+bA$|l(Nw6hnrH=a?58VYKCR?^!E_<=I>l?49#!>~X}&NDMa zzbLa^qvF^nwTGQY(yBvd-RU$p5{Oljy-v#8jM8rFc_Mem+*V%@Y^Ro($ zo&m?s#c7#YgIa&ye#rx>djM(eGGWWJC6IB5zQJ8?%#e5Iu2nZWI7`!5HJx@VLvt;% zM1%UmNHz11wFGr4w@)hTAwn){@W1b(l0*ZeMeb_1iWNU;;2a$byFa8VmraJePIQ;k zN>qafRD+vMOqRDOT8}P{_W=TMU>U|wns0WZe`Gh4ILFKr6umab)46I?UmPJ?I65~D z#acBQT_f@>0c~{I3~@1^9?#-a>C#oRj6#B49BMwk8adDiIw}ASUL0EF*PWT1$`d*~ zZz5&i6P{Ruoq;Pw&|f!(1)H++#?;-b_s8U%c4e6dHv;t}xFo{tA5`W&6I$n>>+8## z3MJpvADdTPKnTx~A;E=hu;eh?)LFjz75wAqm|);rkp<2*9q$3t-0b z<*nFHryGxPcMaV7`q-2s52<8!vNV3V&v->k`HpS5kxz`G_e?=$aR`(ULv!P zImZVQf$q0COi^4Ld;+sdbQX4gsS-N8qf5|kD{-s$D=zNQ|DowDgW}q{ZXMi%ySoH; zclSW!md1hyx8T7&xCGaRgS)$>aS0wQxVyvM@2&d&QdHAyS!>NX$9RU7HN(`v#=E*@ zs-erVH$IrO6W43bQr*t{@4LnqS5rUCD$Z=$b3;MJ?hl03Lg(oeb>159Ap^JOx2sEFe4s9`xd3}TB{u2P z(XVLxtCD?V%)3s}#Wz}7_e34VCB&zjqjQBn3)bRY)@yD-}J8N#w%dhpH9>cQlxp<6rqEJP- z(H;$RwqID?a2x2hUCb|u*2PQ&(}MIv6nR5v3u-w#gxl&wR@W<(=9l8hjEdvH%ag66 zC|hzULhu0)I8@=5r}H2&C9lk6tW9p=znWgOzhR%F>CGd9!vlgC}De zCQaYVtxEQ3GIK~c!qwRsdoo^wHb?N%sqdo-SAM=eEBF}$Z}X2a8H{{aeD)_TD8WyU z^bd**Nfea}g*pnhI=o-eO8DvN4d>(y)1>p++W@@}PC`=x*8n|^J9 z!G@W=KRi7u>}WxQg7k6qfj;#9H4#VkzrDyGC1J~G5!Z>8?eJP(gc-C|ggzQ) z6qiZJ3iB2=Qbd;1teKS{RCeF@q11NTcY1#s8?zk5ZRSF0(+rZG&7_vGX+u zGVl!j{iB|<7G25M$2)vTwmR0RhSuT7Sf}~ri3?)Q(uBu%1r%&UGC`pqjt_%LT;^Oz zbInSn$@=k9C0k%Pf7*e!qsIN(-{6C$tE;DExQAK-Chz(OI48xVcDtyguFUpbp#O?bL zk)jJ(^j((d?GvR%h9sWkFqyf*oakcoWF&PUI~_OKj+mXE{o*ewAi!gcms%`Q5GhE2 z50w&Rh{yQ)6>YwhftZBciW7rbI|9#xl5B=*J;&PJgu{B%95qS{W`+ppzLWo_j>KjQ z#8o?PX5A_`Ex!)@`&;jzDq|eN6ZVBToJvz`#7Nnru`AoA<73mEI{&+lw-4Hm{K{Sp z9L#4Vrz5>`W%7YWMM3e;qzuLvthMm-q*mkZNn0>dv$L3@*!V=HYFJG5D)eb+7;C+Q zZuBy6T%KnBaXncW?aa-@4*@Y!5TS{08SSE##j;G&w$Z?orK89@XX&P=#fa9v!(mvL z@lg)+0N1GES9wzJ;Nm7s9{fQWV~KO~qFL{3DB7~tG3>&GMTgQ%QW$2envMm2fE3oe zIlmIxr#^TAN2u2yK0^m-mE$$nG_0s=^N&6HXC^^^TmV`IpRNz-66?T|D{8cWrRByd^s>hEo z&LBaWuNN;mCA7~J33ykFV{Db%EwFx~PN5w@mj*l9qlRf(P2qTOq==Jd)=3Xf4~=pV z*F(cRdvRnH4wn3=FW^8_Msuv&S~Q|a;2EwT;nZ1%#k`r`#Tr!R~rwzu-v)N{RWvG+5|#__X}7juc_lrgjb5$S@Fi_w>!SYl=aF1HLO(j#LPY zr)d8}=yqz)6WYzqeT}(Vhi1z<7BWQgV9UD1(w-H{s}`3v?@McJ2>S8`MaJI$xahZ> z(lW{F=Yt%FECMY=>PAo_1C1^iPmPtPmbJEMQ!vOZoZLvig)vNahA`}Bz=5FzJOsX4 zZwT|IPvjTYcsg9JsB!Ooz47&4y34{}Y*1T&Yv}$*GOMOPY}vaD)`vRK7@H40I2CH3 zjXuGOSQS=gkaDJBXdQ;3Ev~}YpT&TDs1J7vSE60&9RbbczQrN(CGucl{y2%Z(C8ph z`bQIf_Yv@yrQ)v+=rlNosTb}#N$z-vS|PU#4l82)`0s}~YtBBDp3AfhUmhQ{;p0|- zuD7+L!L(C#ewH@#lLy2y=24kX>TNqIx}YhB$}AjMDLCCsQ-#1e^fF7bNlLMMogu`Wd}f1{QhKmBE{dLI z9+@(K$`@G_5k8}pszjTUH=Fjv|C3B=*yu`6A};%CFY)7*0UMfsRy8RP<_UL5nrp#> z+Q40+Q#S&Z2k`P)5*#CQWm|BnmUp!Z)&o%?u1uwb;wF-JH-XIk>q1-k-L$Ed`CLvs z_3H(173jNh#@0_;#{n&Z9__Py)|IW)t zCfKNmH4cepl}x4GS6iOk$riJ%&2*L(g+B?A1i-ew07D+H7S}t*w7(qJ=E0%A=ofQD;=VV zN*_DhLg~Ho()I>!PiFYa5)|5hg_BxHM**WCxdtop6COIu!8TK_dZlhlAg$}PQk5AL{<+Mg& z?UwiGxvN?qV|=dCdHk*Sb~xq{~-C=rn(NvyaIONhg%7wLMWZD2f~ zG!gS{S~`L(82w@`eA3S#Q&T^!$yHvBncKuf;(F2lP{m7#r@;;S`U}X!xc7`<)%fvd6Ni(|>|H^d3{2$}JsTb+vh(Zfv`Hx>#a ztyZ7F1`I>y;Gy&9V-5c&C{#s7SbOEHSlyI||MST;QK_WGT7wdVBRYUDtS+|1rg ztMU(!0`gCpUU>-i^%{w|`vS{kZVH=OeJ34Ne}Vq@{-n0a9i)Sb6jnva9NdZ>Wwbd+ z)uCF{sK^TgNufIL)7`8%t^t49_;}(QHS~zufJQ;6uJpwJZO}+q?(70?{QklERJA-0Y`YA5REAZcB0_E9DT=hP7lx!m{$`2Rv zz=)rn)E8n2zEv}I*lp#FPJd!7$4xXu-$u8!pYM$ZXtN*N^1hP~nFnV=P_X0=3Ra71 zS=M&D&uulf9&he$U@vyQ2W*c|OmS$asWKoTJ)^)9`?449jN)_X|Jt9UYBa5 zlu~F~Qy<_UM#}G$&wvr~B6>^tj;FBa64COx-^g9$5tFUtx^N*G^ ziAV9$dIGFdKlEtNdi~(8Z%nD(x&^&u*cl%Dx%G-1Wr$vx1d?op|hXn`sh!~)+6 zFw+AL$-kYiw7GqsUSE(CPnS~?`)})e_ZcD6>vPuU;z=PJ`fS2ExgI9OSCRKif!60> zoFeM*j4}-TKB!FAUW94tC-| zwuN4D)#h~&HJ1RBD@EGPQFKL3q&HTa^n8$hslxYzegs)K5U;UoR|*_nf~i23s~H+A*7D z^z?PyP5O1r{Va;tLJCEnRp(US9&*1|n7wS9WYQ`m2!2)1V?d@eMJ9LL(Rnfr&Dv@?>>U^{31N+tc;zW2E#rQfmDyIZA7 zcc59VzKxZ(X@wG?p@0oMv&(2>>*O;0M$<&4vpa`5-92ACRL`2h(33*7OIQfM7 z#*!JGUxO;jmTb`Lw8_6Ry=$|s7J^G{=rD|F)z_U-ifPVz+iQO&vMI*m`rw3}YmrNg zZKI5G1dsOpK_@cpo$nFtU!y}um--^9K{=QlGXC;fen`@mX)sw97WYNr(_l*L4To3C7cc#L z`1Ds*MaP|~v$tYH2+)!Xa~dEj$+|xCelG6kZK}{_C7`XKtCMtPSeo?V81lV` zKmLa<;~6Z)sKIiILySRLh*FAB&7CNyFAvwpIs^4eZf{4krPur|yPzD|ujHEqUAqvz zIM%FTw)_CK8v8dd#9)%4a$YF<#EsJ|H_jh9g!3Wgw-qou0sN615tx+b00h;BPPq&$EZW4#9SPD?R^>OyN=8Yw2h$xqAX<==I@V-qW{vqMb6aH?pwrZBrCp`#LW2#6 z{a_T@6|hD>Fm7YT3;{l(tt;sLRrIRUF2Ls1aXjgsT3cf^YH`BINw&kDS9{GH}J zorNhBLM6%aquM(a>RG+hr%(_2jZYF6&K{vezRDLisWvd^$m@LsVHEN@W0jUH(4@+q zFgGNqvq2xgdI*rD!znR_Xw@v%saDF_X))_@vL$=7##25Z!vLTsgJxX>WEZ43L-LY* zT`%U;X#F$*HpVuE0DM2-W+<1$YT+pO6faH!%TKVx*-t$o`7_ zgO8`Sf^5S}vUQSIN&!5f_)HEXPC4#PhH>A|a~Lxfr=3kIbTDY1`|f)Zun+;u#kYum zT1~r2aKx@&wRbY{Ge5DThsZDpY3kTb{hurARAaOtvUDVJPxU&qeCVTl^>oS1Z!fQb z@+HP}Br((_{oEJ;PX=SrUg?tG&Lf1Xw{bik-7su|xRE~>oTy3^ ziwkwDw%gd7Eo_ayVI55B3FcBhh?iOcE*$_|0+mudg8N}15ogE@9MTf&NEG*l<_i{3&M}x(u z#hbGY6PoPs2RI|;Ego{&&7Okyc)3FRCaaE>7?K~lBhHcL?L15r&Q8H#aIkzAc67cS zr#_F;w_Usm+d_t`8O)0xL70IDa9dM~0P25C6%*+rdBNXui_B66eyx8>ppg=%qQV8WsAAi}hLS8(Ss2 za%H4!kfR;y6bJ5aZ8s6-*W3RpG9__k%hE{E;Q)sllIjSndn&7-RU5!3UT9FN-Bm)-ibk`AlMjBkXJ#;-qv)8Ifq$Tl6Gi!-+8iihSC9v*Sg z8RSvqQusMyAOh260bdU%it&vxQ3*yNp6t(K4ETTGw_n~#jJdvs8yZW!TFTq}qB)WL z%c+AT0ybdzQT4nMT|sDkw&$_8GBZw;Eb{i^Wf~=gO4k@2+VwS%5jP^_`9d@jPr;Bg zi4`^cxJ@WArK4y3cK(KbFLpsi*>$ZR@a*-T7{2<&$vTZO&+pgmvA{)z-bOrb6cwH< zP1ea!Ju84~sAVOaE8OxS6Y&hCd_Qnf&l3;ZZzC#2+y*Q>Ns)|-rCR!Fa=au3x|Lh} z#sG>CFzCR8Dh#=on;njBNzh`@*4*cyTo}o&O|Z%{bE_&0Ii*^Vi_w7u=j}l*ey5ee zyqB@(r3NpKLwAxn-g3|6IhLQ zUfLS`ws*W-7xmtLLhp?4&I5Ay*;TLpZoG-@S(hr&&2?U?ecP^wvJbeKsLnZHeC55Q zZhyoN<=o`^s~<)G%*6J0#DC+FsQKR7ybd{cpIcbCVyghPN{0vsst7TQ8QG!3bpeQ! zQSwDWed8y_(EP4^Hu_SYV}?+W>6~bM}vJ3jCxiitZ zk!uH{!)>!NU<>1mhG^7s@CZ~8tjo%n@vrqud+Q75?LGDg_W*1{rFw>S>BYd26fX{a zvU>7_HQ?A8tY=Fa!&6a-0o>fxYb^<+-&&(6{oXtDONS1Yh=8m;An79!%Ko_;bZ~UG z^~cDpFSFsR_xtmE$`EW(d{Dr$#usnrE81_}jLc!+9z6JO;vn!ux_WBJz7u`<mnlWt;cepPhR|GE4~3ob76N*o&U>3&M^s&icBuU_%utMe9B zb>#)kpdXJ)<$Dx}O$`9?cz^1uju+aT1AaYI`egt)2i(Hk(hIkS?jS8CbTCeg0a0%q zZkeFl6K{-)$}iCX_qc^WjR$%D)~ay6a6;IjM?2DM!_E` zL>1dWUv`Ekh{F2@2jNA$PWLP*pP5!$oc5CQo=7Qt52P@Pe_JlK9dkE3t@df0_aqDr z$u&E!PNwP^4*?ECa?y>i&d#BFJ$rn9*V$%Bn^ppAqojW?7y_Q=o*(wViB}F3n@8Qh ztaLoiNjzErVw^Vu;3WkESai`R8`2kkARDCHf3f!ds;iv_Hwr68&Zv_JaLSpO4&NFB z#MH6xXw2kN4mUM*#2II-OpQSlBxv`utK z`XjWSD>V2#3>=0kO|5p|6p<~8m-j@8d(Z*XBu5__3A%xke5>T! zjQ0T3bEzR@Q?~Gzn45ehH*>9HvTI3ye?Ke$0hqVLP@R+f9i&~Rjukh2cy`8s3=1S- z7y`Ja1c^&Q2q;UwNGdRpQpC%FF*EWrd-`YPnT-t%hGc7@4#he_WmXD%v53rNVu#hz znR2(Y6Wg@3G$JB0OBZl3WQ;jC;E9=Rq_3G=bc&up11n+3=k~OPhnxHN!vn%u_kBRS zmP_u+JNo^a8>Ym=+r9ToodTee66DdI11=}9a{MP{rd;P_8442qp_P=(sBu^tff9eZ zDZ2v%Liz&{A1*r+0u7uJ3T9>;myt@MIP_+a2zLk6x#>8ZxUuG+T3g=(peT^(O8fIO z+MjH%WF>gri@n$DSW<1n76*VcR+Hu53sB<+TJfzRQg&RcSNo57EH$rJu<%;g65Hg* zoImp#x7-3Liz)rZCt2ynD&qwIe)EmjA~+Zllrle*)%gDajGe#CA(3FBUlLxqMI-Tz zK?hoZv|CU{rU<@UqeQEZ6aM_U7m1jdqVVi+(yB|Ber{n1NMr!c3XIqu-X~FIk8haW z3ME;_>`fSHD!XhyxHybZ=PK4V zHYygG?xzPn>Ir&0@m{+%0PA;baBzTA>y|vr0xGaAY)x+sytMSZlaUHI_Fs#B6#X95 z^46d2eQNKt-&E6<)ALpnIHc9w3m}=UuNwd(8!rJ84A;nBUiTeez{TtN+{S9cu0Bwz z67208${(}~3ozluh+b{VxO-XEIz;3J9vii7Ux|V2*h`s_VKHSgsNdS-9_;^Q_)GL& zi>aZUJcBWWgQjaqt5r4;KG`HM{wEc9FY=y+bkfpuS~U!03Lcgpx8Z|{9;z~>^?oE; zVr>f;i!KgfQWsC0C0k|cmjb2rz{#;KDMX8o2FS2V#SGYdHEwnOUl8PH7JPt%@$dT6 zPv4lB+Sb-kYIJ3=&`Gmicl2BC_!Od^hosra@E^CQ8{4Eyx?5kkscWLV3>*J%?CG=s zM`>=o$YR1S)x8}p(URM?Vu2;t7B^-H$l@6^=aN^D&&p08hJVL;$7M*QT<-HVpo!4Yt%q8e-V#ry>p z*zpE94YO-rGaG>G7#=RKZ)gbk-lLZvg}NUedq$es)RzA+Kh2@oX>mJ*^V#sav;K7_ z3lM~C^RL}yA@;4*xVq=J&}pu>J7xzE1y_H5>eirwL$`%NbSjdf4Nc{DK~m$=DH39n z&i0c>E>OZe_GoYKAinh@ASBRK=5BWqi;~Ut?NZh&MT2~Cata3)1dVSTyRIlDc<+xg zfs^EvkH{s;I+P0-S@MI1?;B5&+rLhXG$c{|-+duuh}woWgm9{}#jtakcH;T;a(NxoU3@ckTg6Z;h@ z^X(g@mNIZ_!l}!3S%AQ>?YhC}0?Rl#OlB0_Ry{G{eIzMCenuCQ8XYYVs&R`{lVP8m ziC8JV@}mh3BE|(o!{2btXP+DZIhxmHP$Z=$NwTmiWvl436r&^eb0_R~0RI^s$=nwj zNbqSErgYgSsZH$~9RowdV#BHrnw5*pUUa$P;Lnu{A4b16uxVT$_B_&E$|kjRKC)$` zjisHgx=1G`45xboX=O|8T$;|Cy$$126WfpCX;xcdCPS(WGAudPLfP~N7V4n3KfZACQWW+ zQ|A{_p|6`r6u5-LW9)3&HH+Q@$AL~m4IBh9OeMf+3RHog5~2mci{_PLP0QDvn_|OG zkid*y8CDk{6(zYZOq3RI1rQZ8<+$(_Y^d}Fe{B*uY(h6@XKCsb|IKn8*mdoJSag7O zn+rXrWY>yiS6RREM)F|C-bYA<%AaKyH5c#=BLZk=I&J1q>V9vd<}b-A%QWF&zz`W2 zCWD0eKLYxe4+YS^0#b&6j^&IEfJ{9+QlFb!ADEuzgf3fs6!-ct5>*Q@72jSpxS9jR zjs+ZPwgubS{sUkexG^KdBow7(E$M#ZBS6TcIxk5Hp09Qg;9_-v%6|y+qoAkn5)*6B zW<&?Pe;zF`uoX=tQL-Uh1yW?IKspkDK3eLw_-Z2^ZC(J7_<;?K<|lH`)uflpF&jsj zK4iy-LW{Yo%+a8=dL-<6U&#N64*05UM$O#f0l}ZDTa!*jJYBb5e9&cpWh4j`{Wte7 zev#w%yA%3UyqK66K%0sh)+zr%xo6=& zmegp~*o0)G$@=fhC44^yJo%%3v)uf9TDlQUFzN7YxUcW(Jas(pg zNBI(iiK{^;6bOc$>GvefNK-2Mn-5}jd3zBm1_6$SIESUyD1ax=@31twH_`qtW6TmL zqTTP^-Ci*SxcIprq+c)+IY5T85>q4DBQ#vT-@ohYX8^8asvlGiRnKf)p3BAae5$O_ z{wQI0uY2d0hfBc2^uBA>bN|K>xOFb!U|@Z`H2Z}LX|bvWRGUT5H!$sOIxvrzJXT!C z8sl43O&#Aai6U2IT4q|MRk@&VYA8)r%Zdw#6UwxBk33jM`cU5gRr&x0HLzTHcMoGe z2WzmW54g~zK&?<8e+>(STCO+wV$>Aa|6PAK`+iPtwXC!87;raszoy?Jt+${53yX<* zjOu4tt)*%+l0wL9Ecj&)n_}mKMMB+Jfc*(r6p^$x4tx0@9UT@rGUW3ok4iVaqw1sI z0(qSql;1bBb;yeeE;>cOEtsm{fHvCw&xLv#?m7GhBy-}j`62vZh-%r~%mZc{D!Lh< zoT(sJviN~9H^>b#6H_-g9-&szw!XFJX0~lv6^x&VKNZQ$%pGoatXLoc3}T=Pol=co zy_|gXY}y?Sc(4Q9C?X~+Ri$TnUW!R6K$D?z!TkLVhy{iM$=zBIQ2Bx#;0DJDr>-)M zwIzO(|5@;N5eO&N$9PL9rV-MsVLn_B$Kg)8>}Nw#Y`?@inG+?Q{D6{yvwgwoa!~A?FB5Oik=pbcc~X zUN%btd#axWh^$#o#e=qu?SWZ|^vZdH2e){(bKIQ8!9T4@7Rq{ooLy!{*if)y3a5NrI(wPPS%>e3I1A6#Q_o zxy>?+43SV0m(u*^AO``yXfLmua|XB^NiT`I1c28qHOE;QMzep-U~x>TC$+kgAHlkR z|As%!xSu{g75H}j{PASNYwP8ub0ydzf^(jRyEGHY!%Tf~UezAj%%%1TDRwpfhpj=V zRQY@wx;AxBQmA0u7f1_)D{C-;~FdQ`<{3#7>T5)t(HB6?J|6J@UHIKom z`a=-emNzY`KL`-Q0Wh(6a26{Y8@5~p8v;N@+;xr8YAdWG6UQNcF$T9ZSW)*f@W|$!#%bqtvj<+@PZMw9HnTs8PhRkV&hL*~*j? z4ZhpV($X^YX_Lw-PKfInJxx%TfJm`ezt5;RJlKlavXGZ9{Nsu&w8bDT>a;cE6<3ex zA*h0SzIDyT*a6xoR8 zvxT|D#JsMGyQHe^GvaAN{LU>l1;R=zMUL+}*tqmBOt-zW5&8J^%r?I4) zk}NB-9>F-&p}`g_zMK|E!D=DXEM?)g<{eIdQ!h{v@RmBjuYXu)-SEY;>E|k`~VZHkQYit?)<_Vzal#v;Dkjv{Upcb7P;CN7;(>O0A zGcGB2Q6K2+F8O*INg|PN=|n8+nGs)+&CIz_Y+|~ zw>g-TOAS|Hz*0?nt3PI_z5?w7l()_i4FUu1pT(6Zm_x(JR+~eIa$=|Tw-QOF$PX%2 z%%U&qh_uNwqEhn`%XH;g83}zFGWMYlOaJt(w~4UAjee- z=@m5iRgUdg!JvzpJTr23B#qF-Qy7!|Ry^L!*6+M)1Dfm3ph9-}Md4B&4zq5WZrY+! z1iZ8hKMXE9e>qG$@V9M+lX`Dez3OIej&2PA@54?jaB$=Qw)~4Q0}?O_l=Qll+Ds2* zg0*=-^do(`sdOF4a--W{^k$Pnxg;s;gD;Q(UO0C+?c{ZU(1p+0HID2nh96YQ(*IO! zFyg|=7N*h6yY#!>aaJ|S60!|zZJ@5h6Y9wbS6uKxt`vl22411lI^9kyL6r3et0iWn zrJf(Xnj38WUhwcRCWLA+f5jVW=jtuDB2i)7OLJP`6}@;3^nwxN>AATQR1)7oEwP75 zEJie70AYhG4sk0ZGsD4&mc(fm_Vd}nR>V&z0`p9Z*R`xMoVs&EtUPYhzDeaFr8St; zoV>Whv)k5=9Eu$E2-6ycB)Zn>7+XpI zeD$nSU}c}HZqK58J%~8zeisi9SIEfBon#XLI1W+(!jDSG^MuKTtgf?BGK;R!P|bLX z8pHUR+M|JQ!F=!7LS@x!Ja7!ZtyK0F92;qbJ(&^EZa zHLg0MhQT&F)_bh-AKd~b%1eN56`7eS{}d>ydeyU|WF{;`l|dFP zNrWi-SvJe&p}eYE4^Pg$!$kO$UqwY_&?WZ#xiwe8!l#WxBgksGHJ4@dS?ocTC3uLH zYwQG_bb@z^`&OhG;`Ozl*F3018;cpgOXbMk?jSy5N3en^e#e*{)}Li5?J>&~tLx@p z|Li2j4~g%nSK3JKcq8VX0f$H~S$}Petl1kgtcgplw(*UVSO*)8w>gKJSfF$)zY=)g+Lf6a1RO z^*{Z*MlBWwrFW;=M5kzz9YMe+YdMQKc|Y9-eF<<1b}b39&EQQ>uVahZ7kw5|1bwUqmXawn3TJdxgMl|?u32aB7C z88yol9B8wrj}=oznX}FtB+5?2ppTgV1!jVOaC3sRqS`{fw4`IJfXE3u;gQF^rfM)7a zGA~Dah-rcfM^`M9GEtu3_;yI4h(UAe{Wras)us64B5K%m;S)kn=}7#)rdeN>*%cBf z_WH!`8;(0wfM%v>laDNr4|ChFZw%o>^0n>gWL2}}%XSwgFVqKAwR43)?eoV`L}rnR z8|oflzvW|E{baY=oYu_CIg1C*ko~Mk0`XgNAyegn9w&(Z8E7VVwf|Ny{LhvQxHs)R z;Zj+2o9#y=RY}OnSrS=;V}zyFd)@rTHS1@>o_F7HrolvxxjAMOGRRQwxEJQQIS{^2 zxLlQ1iRn4mfIr7Gd=&3+o>P_0nFcRtO;aIoXw`nH;a-s+TwLa zp4s3nD*8vK`~?RdO%5EnpA7AGF}7?6vo&Z>?42%!>NTd*pBXjqwh3b%?=OuBYc%s6 z4JwK(D#qBl>f{7GQH)e_WSymmmP&#@gEiyfw6Wb)a&YS28t)5$ptcus2 zHg<>=wJIEUYOZ&DWlVmopl+K{mNl>_bu7>vAi#qYoXS-2Ml5Y(t(NJ2uB1K(eho}N z^Fr(Aq>HDe!2l%`Wl*8jvLyo)uGwR;-wjRy3}GP(MM~^NO|ZuXTTfLvonyuhetaOE zgKd29mY^Iu_V%Nd@#3OMmh63u++XaYo!@hG)KU1xJm}KxITYas%>AJRiC$!cBOc68 z;tPftP?o)+YO72Oo#4FE85WA7thc)+P1SW5E_9vZv}k(N zZjHX{a@`74nlCJAiHTHk_>c=wkd0~50nc64 z`&&x{nE~d{ih>Ji+QHLj?gt+2z{5iXFZ(&8^7`ib4;At}m;JI}by4;ks@>8z37_g1 zGuG|rZYMcrgc5N$`Y4N)Q-a{?{5iS>qT^U5RJVshS+&C_)2KAZ9ie!d;T3*QQ$Lnp zvRNgM)#M}CE_g|FhMs-AKp6#0-PwCyQ2XQrW}0L=+mW?Xw+|W z=cYGCzW#=KE$bz7r_-nIW24Rv3P`TfSn#q1!dvs-@mAdWkdrm0U<mB<5?M|cTtXk&UF8uVDSMVaMOVwI<){y`9j00BcHfYF9qr+lUP-W z57-7|iFA;=2;RorRJD$|B28!J^iMvK(K?I@8w>VwEsyg#+hf$@q2r3lK$99=Sgw>+ z;rK~O+cGH;(SJdQ966k2@FO`%*&>>A(`?Fe9#=ztOK>IaZdI z@G{6ilmraWQXHyt1Y!Hb#H<(&?}UwA$4Wq-cJrW;lFKUkprRKfqt;+>JTQNJ{)QOv3S1xnWE%K3yG@hb;;;or z`9dWiact0egwHWj&(?jjTT|cKI3DP?a}FlDs4;uvzJ2=8B6{wF7b7SBmhe8lIZZX? zH_TD%w#eS?w%?K=Dn8JpClR;bvq|vw!trUXEA&elSw&sT{{Y zv2%aQ_x-@9o`?OwH~4RU1Ls$h?^gtG=Pg~CHGZeroi8OlgEcQlm2IbYgx4h;ub=X| zcamSGdY+L29!og(UeCWvocrIKX;u+TIb#R&O6&529oh((;g_$9+fUx;E!9yhj>P4| z?FMb73pTfX!nEyC(B0%-Z%zbmFZ=J&1A0r0tco=rQBZf437;D}`h(pK~k zZhn6~+2NR^82$RaUj30^TQ#`j2>%nTu6>WzdjgN*EYYF|mig}W&0PESR8Nqqb*NOY zhel6)kwOB_4WLpV0i-%LFKcj5Z_i#mU8|06TVaGSfCw@WfEh(B3$_OXl+X;%4iz#+ zI;H-z=d+Rfm|ubcA*)V3Ilwcsv_yn!VPWjQu+Z2pcJ^}DV#`Z%vetyQp=aDdb;4D@ zWj;I-4^VIeF{sgj!|&l8FuKj9LxrQa;_Dd&>Q*pO9S~T>-hMz6jgY5meX{_l z{3k3@J$cTAe7dk3jity^;Y>;~N|pA2kMn4CtdM=<$5h=)|5sOm7pT`v?c+i9{EEBm1boe!czo`tUtsEQ$awg-U;v@T zlKzvsXz>`39C2a9v_1N~gec&BlKYK8OUj8ZMI^^MJ_Wq%yUJlZ+S(~ld|;#svw#AX8yChR(5vLLnU&E#~#ro zGz|@mE)M&#Mw$ffT$4S-pGg?VdnnzmQ!P&skc~8%sDH$_%cQCBf5!?T$gq#;Hmw=a z(K8tu9p!w+Bpb#5fydcB6=qo?#%NG9!D^NFrx;HdDFSh+{Z=c9j&>pqyWembvjIQT zs(_6u6bmm}9CNKF8`#8w)|IZ91F;g$<$qr#(t#G@j2%B$>`m;m`^HfQUtgQ>`LxnN~^?GL~P zkLAL@{L4=`IFG&k{XZs?RJ5qXVe0M z8`yXXk^Vh3qt=Hc72765RyOvKM1YPB^d5kdF9TGIy>(NXFAOIn>XNHoHTUu|6+(ww zx6wWlxVei9m=_hIwYMT(3C#!nL2!KnFWW{{Halex%6w!Uxe!ScW zfkg8S%p`pf4#fXN5$4L5Eh}T8!N^ETr!?$pk!ja7JUffiy)ncI5+`SzK2%iI*1T~O z>C`@oP0e`%xzWfd7Aj8Lep(DMM-g_EYCs96R?=e9MS#PXs-?5_ieOGp-2)bNZRuZW zV}GiQyxq@>ysOKCZ9=G!dHH1**lwSwHoBgx_22^E+)xf)pD|;}1f3HL&jEoeL;HHJ zydLE9J}}HBA{CMEShvm>mux7Qw*4UDdD46De|NSXV`T`asf15I#vj)=cFLxeI;^&* z?hfPd@bI*eE%o+(I91OM*{@?;mai)|^lEklxY1G&kOJu3Ke>`Gh|LYes zrzu;`G0uacQ)%ls;%PoCn}pANj-Aj5EC12x$P`DDL_{(IhR!9f%SC?IEYFd8Q`q(q z4+m?p;vY7O{5rb5vP^R{u*^)`KKlOA`t?S(dURIV1r=pg@U-D})q7n%LK?_qs&d(^ zlPFyLM2jAEELlPqsVykZ9A#l8*ODasABozrb}(5t`@t<;0Cuxem^|*?>5n*41X@x$ z#NSe2bJJQ5yc6Hw0iNoCc+AmwetE3fB^)e@Oqvl+`Tjno_O?I~lX{2#^ z8j=!M2SoyG>`e6cBIljSLqiD07zqwd*(8G1(`JnElzOh%eu0)ks5UDZ)ioiy z&L$B%BLKthY_aE(kIz}@Im0rzGJ@W})0LNaSG(M^Y+&|^dydf>U`$Wx?5xp7VB*SQ ze-|OongF^O)HT%|UF<3`D(L9*C?Sb-@l0xBsym}HpcZ4v#APBELN}lIk|6}dFqLoS zl=Aa~X^5v`2+?w84c2r+<|vCU2e<998nOH67Yi_5E9LvDsjo+iH{a_F(ss2T>{}PF zZbItM3(Sr7i0u#{{-e*^9N5|;HD6pN=~8PwctrORz1=0&dW?jy^!E=U(yXU#dKVV^ z|D0YFQT7%k^j{#0?hqe!slnU_P`=&xQ#E7MR=#kJE3&-AzWoJ`X@Ye?iVWJ4|9gVa z`wQBwrsL@k=90l%(Qhhk4gi1CO2SQ2Lrv{N(sdQ>UzMDjqCmIwq06gvh)IF{!8vx-dmyB<3(?onE zpY@JrniBazW$El3snYB?;^I)8B6>ACz?+uNtoQqIaGZkx0;>2WDin9z3PiFt8SWIu zu8*S_IVho2+CqQmoP3d1dxdKyxbx~+=4Dq8LsXP#14@duUf zgR(Z<96Cg|6uEuXKtCjgL-8S|XJx7&0A#FEK@+s8h!q^-y_uPGJNCR->J(Z{+r+Rs>9z# zIZVqxh&O-;-RF{{#}Xi?+ucQp=RL}DEHxd!V3G^@WkA_GSdl94KY^h2S8gov7Gxs@ z2hW1lF~_awn3&oZXoB(Cb2};}+yMnaRaFG?0#1W2j=*}*Y=t|d{PDj{d?s%Mdiet% z!De8*iUnvH?XR6{|0YROz*DruHG>H5`oeD+dySt zoLV;jcDnM*?z8yl!1w#hh;u)}cr$aSy1q)&SJD^D`&Yk%0ZJVkK=iU)=Y|BxkUEb! zHU=hhL>`|OyX7kvbaP{TPu}T}YV6Z?S{+t8!-9je&Uho6a>AR~9V=(?vUMxRZlZAY zNiP4qmoUYb>r^_dG!pAu`|c6*rYks$+OVQIwLw&{1pWT)(6g$TXYOAt)AN!#4@@{8 zJBGxtha6W&EED(jiyFITemUk>s$>>y`(S|tuT7qQ&GABQ`ZZU!Rh3erS`npLs%Uw) zw@=RWZq{tCAFYK;h->WSg)B!s+o?vSa)AyV&Z+xx`Q?wj>HX+easQD4iMfwmt&Nsq z?>;S>l>Y(cb(}74v7Mezu0qRP35cD?^Mq(ZH(9!`?7W3qvlmZ>NLiUmZK>HY`-<%n ztsRN@(~Co?p9CJByDn|ppS$2$Ua3e7!D^Yx^@2Iu2De3@aa9esmj@8L^p2qEn>!lZ z(T^W%Zc}1|E`wql&lDpGdHK4PuKzB;e=ivW$Jf2q!z?-!zc`!_1wK~4|9*RYe(Zhz ztI)Atx@xOkgXwy5@LBxg?>&=fD8UzvB*Cv=MgM;EYfiDS;?W8D`MH=sOxta{o4PB- zKD$$^dV2IJZL)o;pmxhvIV%J#E2y3<7;KG(XdhA&;KCRM!{PnW?;MGfhZeH9PXk1R}lMzcWBEQB`qK5tiPGB2}m% zCp6hUc#Gsix5oX}Xj)QTXD+ULAI<}&klJqlkot_Nm<^AQE3G)vPiGFI5E}boHz~(G zpTA#z4-S0Fg!P@uMT$ru7x}$6k&V|48*FPtl3B{`Ub8shVWMon^;L^bslr1rrP}%b zb#~T&O}=j%2MLjG5J5y?grtO&ASfN9yF(;ILQ+6QKtTZ+-91WLN=mwO^hjwCMvno5 z@AY~9glE6)_1Z7@z1`Q&^Eltfd3<2`} zHHh5lxmKAT;F?3^Ue+Po1l6PNOXPST2SXto34~%C7wBsB)MmB5m`6$t*I~P0e+a9v zkc3LMmQ_a>S<}8(`6^B3IX?JZ$EniQzFq1szuqaidrzvnvr~LXk>-w>|8_nR8#p$x z0D8^W>8hn;I+*{A8I;(`;yOwUVRe;W4_dh z-FrqxMt@^7&y}2Nn52Bt%X=v@l$aI%y|)w4rq$t%SNd?C%lhr!Ti@STMR@)$E>~d> zNc-~gkb6M;Vk#@lN(HGA)YVPD)C)`7N9k#ZU$|&tdshEfRF_l4 zK<-49*xA#uy5H%ktl_jSR?3B>djkzXi8hp&_025l#O)u-b9?Z8Z`zt!c6Rsv`FZBI zK?A0kz3HZmPsJmtOGjcd=bzB-9b``rW=8^XM?`0VvblJE+1fKziu6UlUmO7S;=ncb zw(qRkhj8!4AbyA(8Rw>-9S;{t)krB7 z%h~4mBB8zs_IHiJZ$^HQ>ftXX7rQCQSrNzDREAJ`zI0bFSm+kvWhNnADwuQveeHsC zOHUVrWxv<7xT{8K1 zt?%xYO^k@j_B&8h3s|MV6(f>C06^(G_M@nmxs`)x6o$Xid(ZCGD~PO6%ZHI?;u#%4 zvv6Z(K#0s%J5U@SA2-k@?lwHYU&0L6fnck0NIB1jFGOFv)+y**cYRbPZPcZ9>z5RM zd_$N==PAhf; z>M_QGIt)##BU$$3vF7`ag1>v@SHbZnoJ2jUK040M)N0XIsN1B_%Z;vnx!JvBmU;IT zd&$~Je?AOl8Kro3b>P*%`r@z?v};U}a2qPqonU*NzYP5!^ANk%4+UYgOK7@}iU{}L za?#?Elz03_gj8rwg9s?{Y+e-#*gFy2e2t0Gh#;9Zf@o5QDaC2Ls2;QO@VJH0Dc8rJ zj}uY(l@qgLZBU{wgPt96@8Og!`Y5AQVLxDSwukK5wY)LOivz=VAxTNq0>sKA)@!#6 zMZb)Zg9E~|{lK{C*8LhH>(^&Wp^CQQf~0`Vc)a(tV|;YZ}1$NUPQN|Gmds7TcK|NO1M|a!Yv?&#q#fyE?m1mmFb+}2yP?UCIc0GQ< zW05coQ+BCZ64w^Ov&Fjf1m-+upTj^)iXfP%?M0f3DA`drf-{vJf1~s)_u00{bkA*V!bv;ryI*!h{2G>nmljYh9{v!W$%;Mm4h# zBm^eZTNMI|9RR_7T;Z zZ}2vrIW^eOzk`cq`)fT^e$40^oy|g)5H)q)%lUu^-&(EelG6E|)r?*(% z)5M=s1;Tj5J5ye&A8S|Zr~jH_u&k)o1PiJIwV0`}o>=wwyb)ZFN63iP zCQWE=4+286Bpk*jt!{!*i0yYCgK{+n98nKTb63_Gx~6q1vA?p)KQu9APfqi~=-i7o~`90oHr@(zh(d_bj|E@bNF1;}`J9 z%h;CNn4&fw1Khj|YRUpANhGt(N1^Y03CXF%^;qKy+mhw7_j(zoJRQsQL^f?(g-#tH zY1$2)?shqlrAPDcJ!4pye$X>f+*ibx_bKPmkG9V6;m=q5x`?-&CX1Vy+R0J{yHQ<- zPDTmggX7heIhvQrn{XRL+9TM{6Olt_=7W~_!+FI ztps>5s>B?=;A%_sdG5J}-@Dz5iU2t z2I);tPrv0&*XZxY#(7x?_eE|irb$V-@-MS-8JHvk+p{&y-Y-VC+ zenGy{DCRdrz z%P|rnJ%#&rD_3&$-A^r8r%76O_m5|a5uVb%@8SsV{X1sMAP{>_LDZ;K)OI2=n5K39 zokrJc@XvD=yIbz~J>(q+l=TFn+-4>?)3$Wq-oJ6=-N-_OKEJRt4zoq-@l0~++xljF zLop;}$ovH(MFq z&;pi8og?vH&z(?tIWki-j$hRHxPb98)aFSXD5kSF{{G$N0qN(ao-_uMuup7p?Ll?Z zlUr3u76PL?C*3J#M>CbVO=}zi_S1fwho8``&~S!?h^7tE54}KLw#4ojHe8lTH5?Tg z9!4z%+@_(44cKbE5iR#!FR4H3FQ}-ff7xJ^gWUb^Se7f99BccjbW$6Cuj8??aS;|@ zx4n0)`;ZpcJ{nKURBvnAX_32y({yZN61tIW9wx?=_!72?llKWh zT3VplpVm`xf)!6-r$Glwk93K|b9w`JOq6XxVq$m>_*1g3QU|Ex76Gn25h0<|d63YE zb`0$BPzWZza`c$r!O>mCnC)C<&pXw-QG*gcPEDan{!?F{idoM(OpTvo;K|0ut9U*S zMudx4Qfm6@avL6~uaj+iq6*XIyahD~T>7}rn1q4p2{W{G&1c~@P&$uZeUI7qL2WFc z{8;0i;-S|Avd2$ZFHB_)TF^&>sjh!-FWtxp)USs&m7aLFT*Q}KnL<$h=u6CaYf#kt z)(d^}K$0qTIXf11da5*!{FQrmpF*;pgvs6%5;)goIgDK=l3x> z@Sm;p(Lu+&dk;&%`hca5x>wJ@;UFAxUG~XxqZb=L%_zwwoE)RV_c!N|A^D6ghO5j5 zR_dFLj=WyuuD?uski(iFyq;0JT2UdWWa~(!ynSjW$(N`(kjEg&TgS(=aI3jczR@&i zfp2W`=AESdT>6te*Ko}OTOm6XUFaUYJf);DI*xBKg?Z&Wk2aP#+*or!F6skwMDRp)VjU`>j!3%bBJ zwDc17S;CrwU@D7f%3#^6RoQM4(u~7Fhw(jcOlm8}Ip~nAPFPxcu&xE8AVo z-uw+~Izg8;E>$v1VTh7IO|inNRRtrnw^WJ0kPRCPr~uer~HN}IrsZmN2HH?>Z=FJlpE)LzM! zu0`Y;O!5glRc;9%tv@@;F+H+_*GC$MO>D!IZBI>Jl6wxZKJCy#2Ej$iVw4-RHt?Px zh}8Ok1teZIS+gM3xug)4=k3wsev}=v={Gn$T=gCet;OjXmdNr!UH9oqv2efx*LvB0 z%RMhLYJZ{uF91VNTor0v-UN^StMeJg(pRynHSH(ij$q$Kg=l=U9)H!FOK)-(iT3iV z{_>-(N6`n#(7*`1+vwwjy5>kQlMcd8TMQ+(oY3(%p6CP}D%3pzH@x*~prC$jTnz)B z2vM2iWa#nC_2>T_PYetGBm%xGB$&DBmSK?IW&htpu$vKt2OhbXmDEJ)un<8~4Dtr! z6L2k@xiYedA%BwWj?v9%UkccIQ6B{+!@l=X0h=FId_JJa{^JmXwi8`9q1S6H(rApp zGAoEHWLNolI4cTcACMvsWAkuaZs`u0;6XdRt`3GgA*Gr2)F*yON*XA5FHB2pjEGeC zN4KQm1b(8((8Si_X!C3C)3H_^+Kpw%^cZe@>2|1{v3%Px(Q49qK17keV}pcJGxTMM zNENw?bChd!xP7D60#PU~ktq>Ekx+wfaQ_FPI)~No2+|miuR7)=PV81mJDKda20{x< zlVq;HK2#>cYY@5PPBCyQD4Jz?c;9^Iw0+K^QR_Tml12;scEZKomY0ojZya7CCvSgQ z3|#*6X@I}wJg12V3IkI|jg(hCtk=vw0s>bJLEYg-Y%iKscM{eOCqC&PT1=1vly}k0tL1 zoU@VN7gx@$R2LxfU4Lu=w&eZ=32Q7eM?S2IL~R6{mLIK&y#LL00n=MSm(3HW8e&gR z&nxVg8;h|ML|o?88t0F;n2s;!SDUSWo;OGB`UmVpL90-eShM$gH32KfmdjDlAXp65 zx$!wi z?f^}-E_ScAcZwt(8j`|$Lot19WM;MoN)La=?BM5)XZbJPlQzenL}m+q{AH$&KlI=c zk3q|uh$46u|+yvuCKeTUe$NedfJvC7_nDf$Mv~$E)DQrnx ze-QdfoyKld{?#2vxQISzfWiT3H`VgRT4sUt#pI60U-7yjO_(0$`Bd@K`w{_L=9`1u zS6xU8W>)coBrgnIqOeHbi7*pc`XA?`T=_JRv-(6vEPGNaa`N4P8BP1~#G(7Y8LB+7 zIw8_n>?PWLt=Br^a(+`-QnLTQQ_chVrY^=F25dRSlac^*P~&e1S!hJrq86K*uGY){ z)W%!PGqj#7lm+a>o1OkDpz0C2O@4nZ<_qgsvj+{gZWNToAv!;9S zZSpwgNIN3)>6(eJ7yp>x%`&zqnQW=pH zD=hrc>a`u?$fA&M9f9fEx-D57lYHIDHy-O=B{FXd(_I^Z#cUT}M`W$@xn|$uiw*sBW9a;M7ZuPYpBHOP7tuHq35jRk*A^ z`K(J&E{UjPI6h;TOVvp<_*WAhfS#hAcDEJAKWd17Q6dH3Y8tMJndOAHGxd}ws^ft8gh zs9aD+lTpEMOzRxQ+5gSeJi2N2XqZUU=(`C7h{Mm{xxuRW{lKeESyHItpvwn4N!RY$ z9;xXy$XTDbrS_9D%aa4b())Nv#p4Z*V@y(w5$TlliQj$Rsfd{q1l)9 zc9qm2yVqDh!i1x9n@h6N|6`TOfkK4va#2?-Wt{}#Da<)UveUSHrf5g#Z}^g@=!)2q z)oI^3zPw{#UyX2c;mE7v>D|ryqwZ+|JQ3|nbS3*g0@6r4FA`;h_YM0!n-7lCf;~@{ z-n*i(c1E)fKX9r2mtvrVgE#n@N=V|{=r@^15eQ*4+CTk_fFaEibYx5s4Hxa@bKId1)O5Rh zdcs%nmki;OIuukc$Ziq!b}qBVp>$D0DTG37bZa^K_^;WRz1Plz`<@b%MZ;7VGDX!* zh9DsRT&ujiKT|w^v);ooUwR-?0@+OCkc0Uq{I;sZvYxmLGJJAlsG6#8Ed5hPaJ_i+ zM*;Jw4)VE!aX;`#f@vDCX5G@MQgqyMu~bM)iAa-sa`_BFhSd& z&h2~Ok!O0DfVP6UT}x2%x3wR(_Gfvfck`vd(&S>5S5MV$gJ^QGp4U1rEhD_@tJK@+ zvYW%@jD_e+3us}YEm1BT>5IsJR3(D}db>QN4|niRH!j{7TgtBbVfN#Ck$cAkg|3Bg4aI!4*n1W-t3&UKBntLcN;EVZ!m+f4tG0ca=K@P|% zJ~faBEba#id#L5j@9BWS<0jw#yCVB$uomQEvC`J|X(Y=%hahVUbg3@Ded_;J4aC+p zpYkmNt3dp*4?a literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/A20_thumbnail.png b/resources/profiles/Geeetech/A20_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..bf8681167d8cffdc27c9b4269f67f4e98f1771b1 GIT binary patch literal 40931 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≪;Y$8;BR{zoqk6pRqk^cw{s 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 Ibnid^AI@t6JOBUy literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/A30T_thumbnail.png b/resources/profiles/Geeetech/A30T_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..1fd33db1bb504bcf2d09bd9f35c0c95ac6174428 GIT binary patch literal 50478 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 A=l}o! literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/E180_thumbnail.png b/resources/profiles/Geeetech/E180_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..4c3ffa454084b5505deea5a56fd5b27c50b6198c GIT binary patch literal 36072 zcmd2>W0UC4(_P!PZQZqPn|E#7wr$_FZQHhO+t2=9{J+CfsU%aWN@g_x_Oy?Fukaqq>Q0LKt^{@twkGCQ#sp68cE$w8 zZssNc0B-9;8RiZoEiS=7hN!wg$Ivw3hC!~oM;}}i2^ME(5)P|~WE~nts;Xpmq09hh z)4pFP&Od!>(c2x`l}ox6C)6*S2fL}qz8{==HMxd;Cod1)Q=d<|w|!sl!!x$=D}$Er zIE^>(|7s3)PF8Z&=pM;!gYHA&|K)BB>e*TyT(~{nxe{lfP5!(u`F!}^*u3P-T#8l) z<@=C5wFQ54!;s4sByEpS?F|3)-#mA7?M%V<2tIGn^S$Zjhhil35Qbj$L$GDly6fmO z4&%tN=o)G>b{W!YT-uZ73XZ?Sv1y*0m!ueI-u+9em%1~h+1qOA`KX$0eSpit0!D}S zI;8K}+R46^>%P&+!3gfX98l9?sK!VR&0`?@I%GjYx>nmBhrWGznMwU1tqX@qK|dY_ z3C+!wnnd!csCtAVu-DytQqt>du1C{LHoDfqkQV>fyAmf^+NTwTCMa7MpVv2PIBuWd zFE6kk_;SpQw%t}YIAgCF{F$Vj7@wH~Ha6ZS&zFMzheeXAElDvlS=9rx zx;VqKtVvU4239JiO8rlR$(E=TZOgnx!?LDr;Yg0z*t})Sw#SX3-Aw!zMW7t~G=|}D zx=D`lvU$T4??{1{s;=>paYa@4a17T~=S1~}%Z7I>GF;K2Ebq~xVM(^naM7|&`&)`u z&6djtE}sUpp7qDb&5yuxzuNNtMACFaZl(RAG`dGBM1OigR(xF=FeaO^UqH-wx-H>J z=_I9Tw^)0DFqlSCChn(QenP*OAPw8+;dRU8*Fh(T!I!IhJ2Cf=B-CayvK z64frY8FRKdRZbRmmYLo0!1l~9fN!3q?rOaaMQt{^15<$EiS$JkGyAx93qx$uGl8l} zK3yeD6bfs=oTH2Lb;9Ch+42V~@hH`8V&+&0KJo zCnTHoNQ<+v&*c*n%#KPIExoRiWUDOgfilvRZ63x5;u*YX_A@NnD#Ip6IF`SZwmTn> zEvbuCeqQE&OYjO~E0Ig%wccrjT`6qn)+|m<>9G9c&dH0GF*y)RD$!xfi!+yjw?Kxl zD0#MHOY70fw08Tf4?)J`X3 zaBgiakDcojI!Jk20{k>ZiJdaJ;uLkF?g+Q7os5@2o4tG9bLQ>^4 zMZ^5^0Cd8LO^}Uk=f32-QMmDv3u)V z!Hgi+SeVxYl^_X!_291o=Blx5;w^6{@BjHlfE_z7$oUK+uZl~~uIm0=(4 ztZimE(3iYm)q4UnqPTXn-?eFj>nFrFcNaH^|89Ak+|~lz)!n@(P;DKNu}J~%wD2`4 zwR8X^c&mfaQmhJk3Cw6rpioYgqx7Qu*_lw0t2n3(r`cwyYP>rPg@Hg$qwvE?0^_Ql zfnk$4I|B{9Zb{rF81Z~mCNC?})W6U3q#e4+NrQS4q$gZ&qqGj`%^&XhJ7|D~o*}8d z)>$YFFTC!k<*8V9k(41w&9+dVM47z~e;0H{G&XLerL00kOnk||TFW`^RAz$-zRt{V zGAYs3o2R$Y;^Re!BD(F^2;(%_p7$ti5h{;#+<0AO>gWW6JI!DUagvg)$EYXAQtEpR zdKbbUev+;#hJ!M6sVEPUk3MAe<{Uo~b@bYCfdj$A0Pc`?h^e57%?Q_C9q}0%4df3B zRzu*N#xJ8jSTr;4wfoKg#own2k4%uCJq(Gw?MD`)u)3>+#R4{-2ZYe4$N5C?gRX{! zP!~H}-vF5LPuK(VMv@Jn6xymPwHTslC}D}TYGJ@t!3dh<(OwL6aeMRu0C%&)u_W{F zA0`AC@u2%!df22gZQMuv)dZdkm9H5ODu&b~>(S^~=_}@K1n<471no?c~jY;NJTpSKFzeh+TOet|DkRVe!92)umY+ai-8LdbsxH zYSm3jUf4JG+FaNUU>J^t0ZC9m2Md7nwla_2+Q|AIXbDq#rB(xjQEB@?l<_XB6n0(h ztX4N zM}CrX;S@{}PRI|;R!}u)jV>b;6NyA&jY?h}3Lj3P)V(ypjLNYi9N=vP_p`lU0e)xt1G5}Re_M=a3ECU>2w9lK<--4*LXGBIVE1Ni6c-Wq15IX| z;S!$bH^<=)!sW$m$Y@iK2bN3Z6OC0%#=H#(^vm?5T5P_+HUnu1lR){f!Aw61j2}ZQ z)Kn{<^X>Jf0jy4$o=TC-Ksg4~kfmeS1PI{A+5ThM$CDw_i24@bh*YZIz)UDh@8RAf z5tlCKd204Vg-fJ42ZJSUui6zuOzS0&!T_q>mU>3j-H4g0C-MF zWMk)`G*q-5NxWY{;j{M$4ypOL z5aYrUIM&)dkQ3^|W5pAHF%FJo;)?(IF_E~XGB&SOZ*r!@e&0Wjvq!Po#U>j$_j_L? zEJ@$;K?yz#I4DA!Uc>-l!+nBgMSE__@Y_W^>OeCFdjTxWlv;WZ>>@~H0BGWWhlhBr z2f9WmQHe`+`lldXQkBwi0~Q9o60nlNG>Ro!2v(1WNiDRkJuGTb451oA;q5QBnvToM7~&7qIFYy~z$xXAE2OtAzs^KoLGQp4W70x~aw*+U|w zk4q*oX-_MOFapc=38KLIN)7h&YWSm+(c1}J=FTd$7;NWn_ z4d_JdBA{0lIQ?43tg?kxv6;b1$MREdrpv_vSpMW#)=0YknBd265^*Nj61VP^SF|%Df_Cb8J0t#^MTIqp6h(?}$H||j&=hCYeizSF zj}_}zusaHArltHK0S}Z<<%%8_pmPQrmtVayvLPrgN}KiZwPN0CVDx7(tenQ_?Wsyi*zOPO|j~dlmjoubLxY_Lk z880|RJtHsuqB2-YuItRn7VTE4>&b}@y>nu=L3d!ITrc-RGiViQqU+;&&RjSNSsM^WT6n3ZVTqPYG`z~l< zXd+LTD?P)plWfg(1d7_0DY1}7BE;$tFK4qTt0q{S3bPB02= zXA!dH8HZCU<(*3?+8i`F5OlDlJ4Ka>7i?aVGdKeHp84j@U3r$8Y?ALc7-?)+iBctK zVlGHz;zu&6T??g+zhD+kVJ)H9F{)Z=m($ME$YXvIt$}gNp{?Ba^wKyaWg51yD0uM%lD9h!j$f{| zfizs1iRpM@lM_<9UHn!4rHV5@YmQIzsjUAKWfhjv7qj7E9aBdZ@))R$g3vGNpT?9; z+or&%1&oBw?nBfx5P*tz9&P8B+h_Lie;}el;E~@Q-OxGWkFOT-RrGbxB2r*LqJ6G` z&Q{NkQ0A9Skwz6_5Kp9)yV&t+!FQ<3uIq~gfP@GHC&=v*u0r1=BGWF_p{4A@%-FaNK1fZO4SL1EdOn`HToBu z)oMPILd)7P-(TpCVp#P?QnS2lUUO3q+Al6E3C~Sd|8L6KA9=CN@UV*BOd{N>3k!Ly zp()6(VZY1ndP|WCq7aam8}Hc`pYdgd5dz&Z@zMuX0Oom0X1MX%r$w}Yh#82$JWV|g zL%`0jcUX2yTJ?2o@5gIL=zbx?B;+9|8i~~|9(e(l`I%E9&Xl<;Z~_r(MwD~Nuq{4GE*hmI2DqN*G#yC&b z&1rY_mhmK7!69VmMN>50kqyK`<+Z*|()(ENSjd`)D)4X$hAOKC=&@sCm!!o zL1B^UEJyysAj=`z!ka!p+NN8^T02D`iq~*(klL240d0Oa8b~rAru_6`m*;VIR9P`m zp;}8<;L8PV;WKoJ?B*t? zCl{c&puDAJNx9)SMR1H8vQ0nKQ)3fv3aP_K0iav^_A$aoYP0b7wY0QbC%lp^4RQ^4 zMXD&dJERkpI#;aF2o@s19smZ_7k{roMSdlBW2i7CAx1g2Fj*)o!F$e2AwmrxW#n_m8PBJs?<1x^k8Mx;DgD#9POHQIZ9ga~3) zWoCAhV*$h|=c@V?)@&O6d?Rjg3{oEq zP?#A%#VxvReOr62ptoUt;Mdbo#CU(}qnHmp%sCd}G7`}GlOZH4M?;B{$=HF5r0}aO{~pTU{)}NFYbs0@3KzPb7a zKTG%0-=o-a6Wsd&$D1ryAtK~Y zBzJrDWR{!%K3$56Hr*c8VwOmxRwZs`=pPxhNajijcOe;m5@rp-?-0mH0WD~ApM@$s z|DD}Opm_*-zniYyvA%`WzlmP?{2$x`d4F6eh$ZWKFPUex9-Fg&}0`Y)7E! z9U}&D0o)q3>_yBEq-n8O?WP7q^2A0A2wJb=43I$X+Xcl3{a2YATO}ZRr}f`kJZ0B3 zo{?#vT+nE$K9`y4Zu3y>dWt7`TkIr90Z_`8mAEp}+eN=v1VNNqgk%Wj3RR`djG<^1 z-ARe~KtTwNs$#+1qWu|B%){nrRjz#3HJM@DwD;n2lJ-DJOnLsI_yOz=Jc+bY|SzVNjG8=Ld?n( z&xaI2R#|l!Qwl+ad6EK8vr3WPbrAqW!5WbPPIB3;{*NCsOU1x*i_owTW zpK^1O1=D8}w7xZ{?eGppmN0k)1WSMrMHYsQEtkUQ{R$}<21$;2_ZLg|>)?#DEEt9A zq_fWFrxU&(OF#Wh$RsTVT+to1%>#m6HXfVaf$zzh)WHM=R=t>fw}<1EU9+?%fNy7R zH7hFCcl5^{IqQrlj3hw(%CE>idx-nKMhPg+ujWgb?ZVHZuW9C0>~>q!DP^DscyiAMx@3O4tU_ltku zsY12o7w_1V>gY*DD_2LUhIBG=qWlW_+xWc*0i_+A5J#SV?84a)c8i+S&Y5l@U-(>R z83{rnNw0rY-%8@j$rTf%2RxFmPrDDukLPWYFEd)-`=tKlu`SE9E@5DT-3e7@DGqrp zxHU-l;EU7u4>E9BLuwfrTZ(H<*r*%_ppbl=b#T$xf`3Ql2D!SqakH0F_)E1U8#Dqd z8a;D4f3S5jx)hnMK+>cm0%$C}%W{~Z)MQ_+Da~!@Zgi7f3;BkG+xr~hP23(B&$(SJ!lHVp5*qvBEw?ru zqJ%oD2`x8&4mw$(RL<|$h)n3Vc1So=#PIcd_o}g)IzDn*VWX`qcs%-|k`FB#f*VdZ zb#_cRP$LD&4U)oBfG6I$M;D7=%|zL8YJf@P=`1F??()$jYFj1zf~sVrcvGvBX?vdj z&25AXyRq{a&-vl%NveRe^lF@A3=X}rx(ykv@WIw?h%0i z78Lb&=|R8_kSW6-==(4D2w}&EhME`kH2-D15ogiF(C(#Sszz{)?IJOMJ*G6C(qBOK zzX6&CM_F0xp1pL*Gt5pmbv!(=EyC$a+-~xvuRyW-6q--T#aO2&9ZyknPF`TtYXI$w z4=ct-6n^R`&P3{QRPi=tQO|g*(6+YqN@03jVw$Dh)ji}bEm7C}q>?C>w(kF2k(i<~ zREHVtb^nH^1u^aoCqDpQ*$T5qqlCw63JCQURYhfTf|fBMP_j43m4h{rrUoqAT~{U4Chr|?x2KN=U3?r) zxA4qTXeBR*(40fqs_JRj3;BM9+fDKRPB&V6Y zcqS%gnI`BRlB;~Mvh#DF`mvSE>tmD2Hj?t=6FHzU^rW^ybDeuN@cDHy6YNL%4;K6z zTgM$DfC&xrSN#DDG8Yn(mk<*ApEUF<2xWQ4^N0`d;|%F36)94~xga2p$!F7q?G!54 zL7+)$<*R@vUXZhxiz{m5fUX1t;zz20qnqmBYJ&>g0uRoONz92ze(EWjAs+PE^KEZ= zZgv3&d8AW{j$q`K7UzVC4mz2rJa!de3*8z*F(WZIsyi@(uG~4p!|UDjb5DG2<`$A? zGGpu_hM%MrXAWWyE@T!DyXUfxMkuDdX1OVsKqK)v=(xN_JNB9Qn}R(l8|1Ky)1a-Z z+Zd`YqV7xV%d09->WOn@9d!&0EsaI)Oae0Hd$a%4`GEx%z#R%gmE%-Or=kyYGHQbyEUAZUKG& zDQP+8mBsf%ac=Sg#=!w11|8RRb$3@YVE_OS07wW6D7&p+cDZJes62iDbgL|FEo>z|Ok4d$ zrnyW&Oo2&|@$&=x1RxR!zyKI4NFbHaohK4U0tFO7OwJ-1qchj{-!dLJ%wA;9F2DZz zQc&Uf^GAgz@EtkJHh0C+#e_>)O^xSe(=jJ8kA##`LPAn8AtCAC|EJ~;?Af)hUbn~7 zy5;&h=fl=k*W1&@$25&j@*I(5>TUylu{jnGPZu>f7?@`8Y?v?%6%|$O&+u6I&o3U8U29U>a%UJ z?mIW2mT}K50%bt4SKd88IGvHxHFaIPV53L(!=`6ouyAlZ1Vsf+O&p{_tBMeeFbI*! z*@;uf@bQxR8q0K~{6Els%PiLNE6%xO%>w&>1U|LeI{-R+mz=#(Mny57dE-E7GxBB} z{Lg>9e(oaD@k6SaS+Xecabz=5!`H%l%A zDJxn)dCwpv;Z}Mxp({=<1cekwe%`Hx(V!ogxcj1L~xq;dQ_bQq;C1>M1Drbn9c(fNpc=e~Ci)n`ekZj^_f*;#caTdpe(S8H)}A3VP09HFA-o=0o6RD0*>3p*SgjYUSp zRm-*d2(xC=D%2u_Hs&Xlhl!4`oA`9NfnfAaXX!P(%fvD~5R4|>(nGws`OxAW;(*cN zWf?-!f83c{oJ=;Lq8^Ef5XDQkf|gd*^~CZ^mL>0U3-G576;Q=TarMUQ(pkfdb^)X+ zg3$r+Ng~A$&n|9@1VJw4|;@7 z2~$2IWs#3MK**pF$O9NawBVSCp*t=HuvDx#-32H}YA|pFtVR&ng(|oU)Hw19LEM$C z6$uFq%&4fUdJ&>Uj@tw9oVN8N5~$73A|p^H*V9aNTd^~CAy8Qt^d%5*ty@O0=V3kg z(D!cb=w`0lrhXI#eLG^px}3Ct$b2}V=$e|oSP?e5o?l$(V&*y#K`XAG(2h&Ky9fB8 z2`crwm&w~q+6WtZ{3+Fg1_u=qY?PsR*aaiIgD!Wu_^)Ba_F+$7RYQ6BT6=y^Pn6#mv=iD;3CTWY|iGB&t*6o9C)ofGxoE zoja;w$)L3w!^HT;{u=_gHMyDKwHqH;+*4(yXU|VI(qzdk9o=}GFwsID!s(hg$)P00 zCCRcg$+D>;Mf-g7q~zp3Nxx<+kzZgTeMAH}l8L+zlQs6{5lShLMnCOcZ?ZOQY*?9t zI*1K)5a^6`p8}>|jaVE0){Z6sh}Fa}AW5gPl^}|zkfbCGdaXfl`}zXD>+b&cKDWF` z0Tip!U1{E1U$QK#uC$nEsS8h9-Zaf|&u6mD(7Z@8aT?&KjC3N4M58U7MDYDMEle&p z)+{zpr^gNvV8H^-r}2N4hhRKx!|UP?Jz1wHQvYMEd13ftTZ*vrbkn1-Zrud^bxaWuNmtUqUf(Y5ZH0HmlY&P`d~2Q_Z@u02QljhV3)1Jh05Z+&3op8$dgGl{3W-tj@0eES^g0HXf7!zV+Oz1TUgDBE!5KoAm zi^4d?9$ngyLd|dH>$qUT!{RBS+Ol4|f4XV4P!_jx4 z57T}G@(4`-D>gTa8OayrH&|9QDrD$1rQ> zUjY>~Gfew6Nt_~5v?wLL-1) z%<;((QPZ7{N+DbH+auYknC&#{Nr9Um*Jm4;-~tCV{4AD~?@#jecb^espA#^bU;zoK zPJ9R&{_W!iE@QS!tJ8A=3hFP4Ti)NC*IY-}L~T0!R`~%I=Qw!9$xbLG48Oe|F}ev< z(d73VOZjT|xB8=^Q%mLz;w++Xk4m{8=DnfBQ#89v#`K8QIYd0(h{J_ZcE zYAry0Jr4DK+@G3g^uBqQR8)`)x&y4%8IT8ZZ*Yp8J4c}Ar*&gCKQz9*kfb!t1oN=l zLp$&)+=IywGGfd#3LEA7Ncy|W6vr5~%xA9;a{`Seobu;p=K~NU_0!Q*mX=tg(*x3H z4Ab3Xe^=b0BL`AAh*C)t5rR>JhGt2#{K~92 zT`DnJiD#(g$9bB7^vb9f8YU&9Q*?Q0mk@S{Y<)qNI0+M- zSs;#&lw>(Iby+pV2#X9!M0+{aI1%Fg!5{?Lq)=wDB^M-7I0)O08?>htXR4v>8zZ`o z14r_LiR0H3n}UW4Vk=LG$ajD9Linnm{$z;S0UC=HKMM2Wpa5c|=-eM%O4K&1n5*WU z6d5)>emy}T>?i_+g_7Q zYeBNiq1ivITTaMS6;u+iuygB7!D|gB2@@xXy;&R$;$(>!8F|IUDa0`xIXgVJ1k5JV zM|C}XQ;g)<(#|TV3&pYrjgG$Kw)mesRZ1CdhG$$j&)LWby_K-6y9LxWN6#JC#dY~H z&(k(OpAC^1IFfaJk7e3Dud+VQGdznc%M2{slSeCC!aKVFN?I9jPu@KTsgX9t&Fu;0 z5m4jEkPdI3W+&(ZOcu93I}B_+Yr`^9oUdE;bUq(G+rS6 z2(iI1%gDyp(b5}{^R-8P;k)%@)v87O1z`hg=$`?Wb?*4vQBw)2ZlP4AJJC`F>PGwWf7 zFZTm&M_g(GWu3E~<0L8Z%u-9t-I$bZt2S)H$D_H*U1m&ThaJYi@1hfDTj z`^C(vQY==OeSdbq?R%`Gw6fa3`o$y1=gin3ew2cl8gb!F@<{#h9BbP`>aOh=3QlKs zk}TQy^KFY&70w7ja&BQ;z{Lz=YVBxP3i)~aCS%>A`{C-w?rtbmQAus!{$<-Vx9g?I zG%xr5KH>);Pe6haI@82ejGP?Dn>~Hq!^in2aMNRj$BMNg`3A=u#2OE8-IC4SypzDr zQzrQCcOqlE(p+-IohL^Jh+#wwy=g1BxLPkuOy{~CP_ZX-h6*xm4hkG+Oe`i)l5B3f zZhT_Z^xVQ>kF9!hf8I$mNyjN`s*gX&f8zLl_F^Zqm;=%Ee1aEbIpfnz zVr4n9^>$pisuqgxmp3NZkNzEu!oVYji?m%GYppr;sp7cJ3Ut1&D=t@SPZ#yHg7`(! zw+F3fc*MM2*Eu;o-5>7!Oa`NC^Rr;>%}dn~#FrjMHB6K6WF3WI+Z+xe%NCT^Csfq5 zqsa(!oMbryv_7c0IxM#I$mqzxwrqB$6%UKrwBLaN$a3!qUw41tWn^HBq4?Kc9eq3H zxXC(9eu6byNZ+n*T(OW7;rwYq>*~ohubT3@;R(0s!SH;Y=y z^^A#}{-MmA%$?cY{p%kN;lLTe;d%fn-+y_R2Yp-u8))^M*9n(@Axxy;q(iQtF+^E{ zH{4j(z z7^Jp+a$iz>M~~3IQ2g|E9(+j?ccziaCHJmn4|*~@Y~fdg=VuaL9v z_5znyRUMy|+Q$J@=CL2Vk6O_u8^kVM%Nly z)7O~=?PW>GD3>sy_0c5gUTzal)KgGL+JDc?m_A=dv+w2spIuy?%!%P2Wn5I-V^BQo zfHwlsOw{vO5i;!C+jKpxTz0H^9pm{>$e1_l;VloCv_&y8Ob zFz2hIy4C>%@RcGBCwVnmzybqP8q`r-;bvQLd$M-ibONtg#Z`z;b9p@3Fb%MqAVp`A>)kEx=tvyP{YhcDT)jKl z@D0&hl&U-Yc($-=lo;)P-G=V|wxssDP#6nfch$7gut3*Q`xUd%V58F^qe7Kx32sao zA{`lJt`Cv69>*Vh%H30tst?K>;^?)RN=UtznJGtTVV34jon+u#^cxP9Ez&~q+=Ha( zn_LSmtGiPoBA|Z#45Gc=14??n2lL&f_c%+OEYt9&ip}_7Z6Tb6RS7#fpM2u%_13$7 z&58gQ1*HfYx)X%-03Fy-eaO9zWu8G3F|Va2R-10Xj#ElSB#V#tQ!9l|XSkxKyKirY zJB=9b157HlGa3X<$CvcVTBq}FIMd4~758=A$MfO)9<@@VD`bNH8#6FasPkdkA>;hK z^<{cv^!TAty)L1__fx1~jsm}0U1V{#^`=@YeB_`~vnj+_YG?QGAXbPChOXlhs#2P7 z#Oq|ksDVsP*9SDz=fTdx!m{;fnF|x=^rUe?7I?Ru+ILLX^K#%fb8x@*;;Zj$^r5PK z0{KDHccxi4uf>2uv+AGCx47TBzT9toTm_^(Omo2tCDNqv#eRPSc6%@GSvAgSdw708 zVO0TGfN+$Fr@O=GAS{63yTa66En2Wzmha|X1>$r*DPOz!kjf+*OIOIub7f(pVnG2l z7;F3jd%Hc*RC%;$`_H=(!lM0Or$0zLh^YhCO{Xz7uKN)_-H36a0#(#>YH@Y=B{ow{ z@SpxYblng_k};p}D;#%0hHq|5SeFLta~aH~JOUVQ1HCw+A1G3{@EeE`!M%xd5beeB z;=|@vTMRVDaLcFi~PUN z5ffvRIV?#wc3A&!!F;0*5zG6lnFk|wM8NDHvxbL9`qvBt;?W_i9y{{mnVq1P z9nIm1n$AHX_%A#^<{9=(N~L1^TSD*#6K8BW?mIP~uZs=RmX`6Xjsc?MUmv-jzjjEddR7;cSNww=F=aKE4C znp@b=1Vsd9H5oL@q#2@v?HlB88jMgcI{^M&jxtwPPEyj*2~Uccp0*huH&|R$URYt{ z_h6S1Q2}kQZs;ySM^RQ)iIXfkJ=2h5F+qqHIlIBP(xI5V@WaA z#{g55{B6ze)xxvi0~p3Lfv$K(3RwP zKmnxc`EWFtT8~b1-3)Twbk0=NbdAQ!@iqN5W&6Y0@bj%#T+$KC_w|M-`%(9`DT1yi z?5u*j^S-R#`Si@S=`mqFXkZ*1MDfFeF?pD-kh<#^eU6DC{xF~6QyJD*-p6h2jXCaw zO+VgvnQQ+^l-lw;`A7cXK60j}=%(4$nbK<7_MqUnkAKQ5s4+3p)H9R9i(-j-&xpxU zPK}K}zqfblZ%&#GhRLuOv^Dx3Z0QdC!SRnH^)~6bMI5sR3k}S3zF&el()5!L^#QX8 zwALvi=N31mFBZ|Zy=$`9}J zE!Mp5$4*Rb++AH?lV<6HI^MAOKAm8spv;s$H2K@D zCA0i#cIXBCNR%~oKg|z)?Sq$d;ddZy`UCr4nWXOD;dRH&{wQ%Q$ZoaX&XnzSPwoU= zPnxqeF3I?KsW=&iYzZa?R&iN%N~bwflI%lrF!tTh9u9t^GqRNOtg?!zOG8;6Hbxyq zZtjA(lp(IMF`{sLYH_&! zTpwwwwm4@t<)Z_nl--9BS*S@#bUWfse!f23rXe|zAfi+X@(L)IO&6v?VjB!BEb39n zfJ4$iLRx?SlKu@m^g#$mc;Ud}^hpL;3WJ;Lki~MPu8@!ptj-!Y^^R9+*l!uvdUq;z zCGJ{7&f6OG;(@GU+b!~+;^OksU94-0p*n}A#fAFT&ddeAS8oU{ZPKr8HWSzw{~1j` zqH%(OxgSRtS@Bu|Tbx_CyNqp^spiaBcT@go-@{4i{(!%1d)Hj;>UdE)o=hG{>3t(z z;cjt%zaD5iTcbb?;93Q>~#LIj9Jr$4?W z{*G0r8Lw*Dl(n!6bDXZjOx!^KiI}nOfCXq;TB^J_-^=ge=}RgWb=lA-jOD$fac7=E z=j*}l`MFpyay0L*+v(XZNU#y8ae;-Z3=&emq2mIl0HF-|_i;&lgkZ zO@U@D=EO7Akz=bHrMN}-Qle~Kh@9c*@?M8m)M1mybnH-4Yi*+ zK;89tUrcuZhuk9OV29LxQRz;#(qtfu3OykY&o zL6snZrCD6}(*0pS5zSU>S910G;W$&b60;F6XPVw{#|`)X&erysAhl}LH~jf<<+^HF za&@NHlT*fQa_cMR6?%i`&BDx@Hk{Ec`@C)Js_OF!n5>el?ed1Y$j0&zE!5LDQnBHF zIn#6ENuF!AF}04x}YH?}po2-C63~ z)3j_m!!^E+d>ji#a|I%sE+aJ(u*R*W6jbEGimsZ!T2xT@Fp9L$$Htz=XC+P)`N@VT`Tnd zyWGXcc_7)#rzCsT;$rIUPLA%M@0O%2y8~mHQ_jQ859R|~#)z(`Z;sy92LLX9=RiT^ zG&tbN*QF^78%y19L_Z8xOSyfAmU9@XYRSh&oaTMuPGF4w1yf|WTV0!;E7_li+M$-+ zhv>qF5;45*X8!`XZdwyUR)B=T_=s7G&9Dkb7Q$ zO{_Z+RXmbH^?cI#zOQx5%PZcd6-Ml*+xQ5v{;(VUd@&jzdMwwR{D#!MVUZQC^*6y{ zncQJs&l`bXRjrh%^GALt0&G0|IbZz5VNs3b^%L!(RGOsBy!7O5_}~Hfos%x@dL|oYc;)C!Pi(AOrk1sT*@?FM z0g=NN?qmi}B)Xn&a8>hq!t%0t=jXfPFDVR%J+T?w(esF3+4jz)Wz*|DZ?gXP;GUtC z;eJ%)Tl>}t%F-;ocla=UQfiAUs+)n+Ig|70xW)vg7ziPAyLBK-q>*!YTG%u7o}+vH zHD%j+iQYpo>rU54aP&$x0%Fd^WhlM+7V-G_TsKr{Zq+gLqLDg2uZSm9VNJ9&H@y3o ziUt3lxqi5>uWo9v&K9FL2N6Ht@1Vgr;OvZMVLmL1g^=1_hVVUcl2&|ZRqT$c{NPF2hnRTZw?t3 z=QzmC*@?3CQ)NRfI|5AUhpPuM`gwf8E#3_X2f!YJQ{?L&9z(YHZo+u>qu(%auu3MU zX?G+g+IE<}?x#Kpf(NfcJ;RiyIkK)deu->V5$n^sw;odn^!#1PlmgaHfh_jwzFfXY z-UzExUOBKP)4Sc^czb)`c!!NjKEir>_*JyO{v~%PJ}9$grRlHZ&j?ku)_qA3AW%pEcsf$dOo`Xi+8{Nk}gcC647K71Y-! zIC-RL)5*EJbA;&sVsi$W#QS@Pe~nOQ`M=IqpB^<8t(H`1nV}R9luMNwut-K!266!t3Ou1a%tCUlOtOVry=u1Hm$- z`j%0wu(H~_*0McNZhT{RtLv$tpwXw7+AVZlujg>RRd;pAtX{%oIpQ0d%@9XoP{kMXy+4N#JDeSLkFC0dwh`nRARScVcW4nmBy zcMz+_<)6qD5)%4mHYA1-BFchge5KieK!g>YFma?&XOP^r>Xhw7_DkQbO~1|%>(`=m z`T_`$!hbah=$d3j)bCtzk}OBHK?6n>nO_4GCKVJE0O_n?VAa1J-A6b$tl=n9Sy)*7 z_MD%eFG%c>RM6GsxcEnkgA$f18}m(zlIhH8&%?#pwa^?Z5IFE3cZW08ACD6k;_+hh z`PJ1hV~t;@s2xJfR8U1L{C!pW{HFAq;m73PEZM}>DmjF}2RQ!yk&dg$@-Vgn8ORtc zdhPjAs$hjuK>cz5rHSvFiaG^%Vy>|VLwA*d0VK?jy-lYHpKR88;5Ig{n?q{Lj1cn-2tufvi6aNuCbuLn-dOW> zXdr^b=FALHBCz5_mK!?79}dt|BSbgr$mBUt2@)hqzpZc2u>AbJes_ftsYksz6 zI-pm{dBAhI_S1#{jS%D zWUAn!ksuj13fAUAjFt=6g2=7JT1#w~PJ?f0b^d9*^GE#A<_7rF)#40MX^Q)$rYw(V z%F#dg1!7LRKKD19b_+yFv!Y8rsL+P!mU-;kL(koGG%C&oxMEv*5if<(3nbaHiDO1k zesGq=$2HA$G?p-IvQX!>Xpo@~>joCvo27~ft#=C}L;0W_cirtHe^z;sTZIB`g`mvvr|Dn*gQ!wea zo3W&#KBBY#zIzp(|KeA_hThjzs7emAaVOHFqgWnCG0hZqjAD7&BNxo4na*$Eh#0cn4ivAr`U zs)2)S@9}zpgjFIHGhO_S;=c@Nq1+Z%g5kkI_Ski2{`SNZJp8A>A#{Vdm1g(7c4Ig- zG$x(X&qf4=r^D*~!Wx?wa|Xk>>SC=GyiHD|l7;$7ul*LZ`23A)yiTG&Z8k{Tdrc;Z zEHtaJtI9_Q6UJys-wxv~AsdN)jt1_?^X_y0IggBKQ#PIg@iI>1Y0&XzS{7TZ6KQe$ z32f+*9&SR@h?Pa@?O4a@_uL0k@%df1C%V(ZqFcWAZ+}w0zhjdBW*2L&GER%DG11GQ z-DB*QssbD2_!ptSBU2Ea=shPt-)>nJN-Bh=p=k=G*`RWV7`Z((GzVmwCT#H9ISCF@ zZANCKhn_<@dcK43U^Cc;wgTFTfl{Kddxh6xiZQW-u*}AP#r_^yaQufNg+6ff^$#$w zrJ3ul_ys4PcQGQ>$8}d+%0PdL{(->)ZRCb7#{*B;<3SyGf)>X_w82D5wA|#Yh!G*1 z$XkB3;ECi$>9PjZ7|Q zFQ!qz^j>oZ)ONb%nC?h^X4n3X9>wRbH>Y7`F*bp8>Q|AQhUf z(b!neldr$UWtaSd70cg4lZr2`TE)r79m{UJ?nHn8U}1|6virh1Z^M4bG_T-PX9K>3ATXE=HQL9ZyXt zgeL9DKMoV}(MMh6ElEpLlXLvh{o)jW9s^}-c%+4mWeGwXsWf4v%ahPFGy&`T2N_PM znbJ^)5sBL0sSsyS2w~VQavWbmNDa3Y*ogf-qWQ&`$gA6Nb!=h9NC#GY$J9nO!*f5! zxu*Xx3}ctMb7$xNgC>V6Br2s+!^~``<@iGnroN^cOV{b@=wMoF3&X>i&@gqeva29R zYP`tdcryyaC@8;pcM*WqYt}Jm?(84!vFGl;{3O@L%^8XOSzV>QETcVR@V`OlvpVXztR9;&kGG7Ir6013@mArM9}7gT8j~ z=x}CgkgkC=5nYTsS#~@=(OZ4;ugG}aPlK2W_kKlV5%NRYs{dBA^M6s)F164Y?`N~Q zNocCOEKy${6mE!SnrjUKudy$(X#GGI_2yPa>jCIJ8+TP!i-ZPo%sm zNXz@*7pDE)|4AiBx_o{{Ws4p5iGAysMV3erCh;&ALi({v;aO^+;T&MnRcW z95p4%t~F8KN?Ck7Y}yV=NMxv3xI4^F4(g9L5xU3A9gkOR>%Px&n!4LI<7Zn#M&loO7hq@%S%Mv_B6MX(8q$nczCNCVHy-f4 zCPPr)ykb4119J$RmszGPj70fgkP?{xMH||yeIr7EuDESon&rb5Pj;rcZhj35sv`_$ z6~+1?hcO)Eg^|Npj`1ANFefyuv@2)ku%uNQ20xhrErlwCzTHF-%aUYG$=2mjcB_h# z&=gtA4#B#kDg5SuDpJi7#!HVEObII%2ui~oFKNow(B`K$tFR>hC8uzVCR7kJG^WKh z;<}_uO7aSf0-s7K{~DB^F^n^yrk{mNV$sx^U^yMZtQ!l)gK)8+VPwWY^!^dm0TP)~e zYiNl=lr;3D2DG%C$gCZsFVkSzaGohqjbo-Ki6?ZP>djK_=1m8f8D204nG!)}N)Q-> zGWEa?VHY!9{8@4ShBu>ZXjQVIC$-6e4=7O~7_=0x_T`CH!5jT1A{oIDPRp<&HD|>f zyouV!L8+a^=J1V2<2gqidF?0kFG}*i251L7ZsPm;yv66rBQPz=Qypo(R1@J#jd40N zvH<=tM&Vy|=!%sTg_Uznr1E9VV$r}rE7{PK8PLk^1?E+e^yDO;tBkTkZ4^vNM^<7v zDUcIQDw@daCQ?Z0Z!i-EG6Px@T1GHZYZesB4${7U5cyL>!=i}ec9|?f%Y~UO6Ye*GLLy2|;bb;B zgb>-n0L~)4oc#dvhN`_l_L~dirI8k!h7~s3FvwX9atK2}UeeH$SwoxB%t}j+0hbKu zUs24aoe0Abq{YK*?}>H+3OXnEd4GFdU1%jVPj(G0CBv4q5COGQUe;u7K?$5m;3B@)WX_)1xPa1$|+&zJB$}nE*63gOT;f`LX6imrWk!#jP4ur zyyv%qk_|nXZD>oWth8jIP_`&A7~6t2EW91YCx;E3FQ(~(fE|`U;_bvgwvo7o5TykF zNzQVRx9P0#ejEOFxM5Am$1@ee=(l2y-*|oQikUusb4N+1HEl^IwNseGNlFSUI1P&s zj+c}CNg69oL~%}}cV3W|A9ZL^GC3x-h899(l-p}~oQbeubY56VRx!#ijFR)d*Bj{z zqwM@9M$q}WJcp(Uv{Ej|WOoY5DZ4!@h0gL2SWP|NzM7k)A*QGRglB}zzOUa{?9?(ju zyqgQ{pLjG;lVjquG)BM2-_bt^oMG8}VcB(o&Y^HMG}x7eC7H~C&U!)PACeOUpz(Uu z6|oP%Q)rJL^8?Rs z61bY%eV>24M3~7C#()GZ9RI=y+bzO&g+OLTS_q++06m#)XsImAp0pZV=@Fz6y|#2% zCY)bmj>kaPkNRkXH#3EaN~n|Y6J~*_iAhRwf0O{Kz7c}_@!Ty;a z>sFF~Q$uS)SYFB_JULzzwO5OoDaGm)gB~l!UynBlAA44Cs0_Ir>iQq1fK;;1!UAheRn zF}Y0+g{722Xd|>;G21!Fc`MfA&Y#KWe=MveZEekHLD47JpEMPsGUH%#{{ipaZGYRD=BR-P#8`h zKk)B=OIHk(1l*IIVLlpr_Y!s|GHaM8B3rv>xH4`t^IVq^O zT`>k^JQia-3NX;dcOs!eEAh~i+JoR8rn2X+1cJ@n(7hzd<6Im!@ zj-?5rkq8RtUEhn63M((sb)y96$qZ=2Fl5d$QBpB9G=#3}L?V$<+R>{yi&1Z3PF)!A z!RcnCM$>_st~rm%Lb;z4Z6>v*DaM#9}dYy%Z^& z)PU9_5ldkMLrTf;@GwFM48y>`JNpyygP4f0*N$a6RH3-s2LGlInhj z5GWESfx6&1vjF`_Y}6j=FxK|@;(pc07$N+~j#47pscPz+m)W*d)r z2ztFcP+loe5>Udi`XxeWDCx9K5E|}4BX?xCeJ-M~7)EJ-1QLm~Eb@5^!!W3>sUew6 z5RFEh@O~-uJ*fd5i$$ed+8>KX3)Lu=Wd#DdSet_|uzNN5m_+{qO{|I(zq$pygpQnW z^Z1p!P&|HsZfJ!ar<9yD*#RAmO4mM(M5BdfGg3-S(;NfD;#zm?Y(qaIF`T{&$al#-5*Flr|=1VU4&B01zDu9V#gRyo^F;q~^eV<@G{+{ecJNQFXG2q6sL zW8Tj)P}E5!gOtpxyY9M6*Z;OtsOtp{ZRk3dhq`l}!eW_mLE6(>FzbJxx0$*3*u|>H zgPPU^ao|C%6@(BZ%gfOX16|k9_3*&Tw~st}X-`k@f~u-YKouO+?ZDQ5<7jTy1HunzdZh^`9B9}A%xUC`3pe!0`4KcF%M0LQ73xYUlF1~Acv<26EGs;Y95=Vcy+-bH-US&1K!485C~fQ<&wZ_Fnpl>FWm%Y} ziD4LMnnolN2^=@=_c;ppPxlW=9hpU=l%l4ldYj(f-t-1D=4`fd)d%nXPXQWG5yL3# zI+`Ykm6bU+-wGYy=8Y=)!B;d%$j6oxi$Vrz-(s`8y})pRlt?7JC@flL_S2u8W6s}X z^N*yIvt01y^Z7tvyNlX?e*WN-7ig}=9?y((fvxL$;d4yWq^hclXf#>?aVnLXBGELhpgjBv${(RMO_R#XN+TMLzLUvh&u#BmeZl_>pp{h0h!{TYV^?-q zSfN_c3#hPJDE@^I6jt{q68S&R`(D4}Sge4+r5?TZp=FxmUYpw5x}$Ts+!KjJVnW}~ zyMuUlE%$HJGy}hbd)#a`JL=pMi3EmW6r6MSv!#^eayho%dh5a>bHTcH?ONV?>n$oP zE5|H$cc<|CFa8{N|KCCg;_*0}Zo1(7cs%~?s>-SbZ!CQ!{b>Pu;>k%;S>7JtN-1)= z9G0{KZ(Om#^2NFud7ty9p1K#<-?Ya669i`O>)m7cd+(*wBlp0vtZ`d`&6qLc`GJ9f zF*n!$x!%R&-OcWKU zKI$iE*PAzQqglGH4NsdoYn#tJpfkB_;ai%fB%RKZ&*jHdmxMKt2?L<_V!AidfAPG} zdoQT}HU8tduX8~hHa%7dK{k_SeQ&=5Fl$^5eb?Q$=TfOuw->111>ps*Qfic4>$PwF z8HKJHl+Wj}EQ@qH&EVi5i9~|t=4P6ko0&6b4z;zl2qCDcsiCf}j{5p~Dk>^yYHDKo z^y##>xAXezuTx)NPd1xn?%cUlR93LsF8om_HOB>X^wIX!*(oP zx7m-fvNCeH97~ogA(>2K7zUl4o#?twdwYA~SnhFGtXM%lpQpOInm6Bk6HU|DZs9^u ziY>R?lD3WxzOw)RJoEH3EPwAkqOsVRwr#G1=^w}xWLBA`ImYJJb)EV1H~HTC?=Rnf z{w7<@d;6U?(w{j%o7ue5g$)K*d$?Pc8~*m&!LEH*EbJXL;@Hm!cr}P0Jl^NRY(78V z?RRoC&E|FU*(}nM=n;KFGgc}qEB}_y=SL-H`5j)biKJ;-fpG}p*ZuGDI+U8Gk;!BV zi`aV|+O z$M0;5gLq{Z(C&@% zu73af{hB*y;dr0-gUbb?uxF}Z7T5<3gc$eQOl@t6w0Cq;TU!%4{VT{OHEpMJ)I#tt ze6Ln?ffkKMi9{lSlM;gJ5e&nisPz}_H2i;ml0I~< zy%toW6_f|!|2t?gxok!d=dEcP!lAe}2iI?! zd3P}H`@HtI*ID%LQhtgs=w7)0uc)X9q($A&AC;ixp#Z(#!5__a&);jl`MGWP{NnL4 zw%B6xqn9jM`lWdrE||OQ{kKw|x>HydD~mKVG!|@VuQm?Su;V502WcknV{Y+4kcr|i zy!A)Bg8EJu`+Tp)k3XZ>jmHnEtKC5@^`!e9WPxN6qNBVWYaX+aKpLH z6_pi(tt~UZ_^E5?n%dfEJdrH08wdi&Q50*!7&bm4XnuEC)}22Y%DW{8X?p(+_S1S^ zO_a~)(R7Wf>ME2ai(Z@Q)2D6I-nPol3D0CnBogFuxxnw|Wz5mT98A8dnG` zDV@Rs<;nMOcBI0!Vk9IENXtSvwz->_A)FwADhzGX0flKUZqkl|Bg~% zNekt14lU;#m760XRbhm*TX-RrXH=h*g`(q8yO0pHwodtDYAAKr)RvaR-+p(A`cwcd z1&MfBjG^J-krBea8|MXwcMJ5I3FGBl1UX86v%XaqeQz&iv6v0Ad>*0fdIUFHEfR^?gFP)UGnqnSwx;VS0m`z0 zuWL3~Bnlywoj&AL*=U+(zfWpNoW_|#M`!{|DSKx@co-&aq)G>f#-eudg0%PMk+#9E zd0>N8(=>Dhx?x}`3(JxSbS*DQI+C zSoA5#*7k>u$JppjZuDp{t3no9SRrmuC#76AN10JPANq}dF6r2C_DuHNdoQx4#iFaP zXM-6tu%yMnKtHuLwOCRjG(p6O6aZ;j7SgiNU9-vk0VgBQ`QE}F{UMw=O`6|^bt-Z+ zO%(cd3s2^dTk7Cvk~CdILqq7IkXbi!PwZ*B0zqnUfJ`QX&@}S-yyG})B$G*!@dQHC z>})(IJJ1`fTDx`)Lqo#_4XsvENRF@=MeP-~ zIh^fXXoci`zx5M|L>L?#q`keJSS;q_SnU`0_xBU2stCL`n{To0#!KFKZQq@D-uwma*4*E2jc$keIR*mS|By!qyvL?cl$nGEZDyUFLxf;O`=;;hjXGj2+# zbJEH&J6t~81xq0qV@XH*%L2eHC%x2e1{5$y#{E}}Z2!u6uTsK!%3cuLZ@(i8=5NaI z@KE8N52glLwc;a|FJDf3N4veFcoteVo28|tl`F5j{2*P|UK$u2j0+(Wue|(f`R{)F zyBCt>$s>+B>c~GgH8)|ICXq;ls3!V99ojCRsg1>Aq*5t654YfKNRo*JZJpix=7EP0 z(!z*D>}^xZ0yb@%PZexGq;j?_`xq_|U0ck)^rEn3o0jFO9P;@*3eR|D>Hh5k!76Al zDXl^}XFi{2I6cI!yX?jnzOXO7eZ8I?!U849=PkO|ucxLw9^?mzxf?B53YIaP?gs?t zoO|}D*UXtSmv4UK|MyM{^^g*o;`<5I&It6mPsm=qN}TO{2*LD zd*H9{y7NKz|1ZAylDPl3_sf|xXFj{=rtAKHEe!Ys3I1A*(CsbLbt>GR%FXrlJn+=> zoOa6h|0ix%XL~1y9rg`+*7ta#WVRzSkQ$=5rwe0))-l)SnP;Ajf4uSoBgjPZN_S5; ztu0e|!Vv(2@Nii)Yr-g|4sX9CdCNUT|SxLjB3Nz0~iQt6BxJxkOuFx>l@yh&A6 z_4N05Q(0BT(D1NRiQ$QSX&OUA!}Rs`qU-vYYqRUFyS!5L8bzaQzS&kxpEiy4-Rs$O z!R8=f?b%Va1ufRYkjH_!~-*=bzAf|05a>6#OuyEeX;QF8qfz%U{sW(fj^TL3i@ zIThFrs?AJ{_zii>DNb!xmd@&4zPl zkxFI2sp4?0Vwd}LieH=?sUuJY=Vl~+BMM1x!b7*|nvUT(S}28-W&sqQK~@E@lqZvP zc6RgZ)6b2v>uv9Rgy}F0gG@S2-}+wa8|n-n4}bV(TW`BbCYNF9t1kzq2bdj(09399%))cA`#H+MPW#Zp&JOLkVu3cu|LmgY;PDE zmXw&%#Ly!Mht3ni<;X1}(Fmq#kr~dAOjI}tOBQ9Zavpp9(Oo;cy0zhZ+^h>h5OW zFMgGQx8JY}LIa{^kw}E}@GzQCyzs(Hh3|gdbvJHw(n-hPamYajGc-KR_So98M?bVsHv^vqvh}O&(~jOzkR=eX_>sc>|M$$D#+!sBoj%{1Vck9n>$uGVQky+ z6M(WLGM`5ZiA}O7a%LV~GY}dm96v%DpxaR~yQ~X@Wr3y<)eQuiCkQj*R2#a6Y35M^ zyLQr{0j0ynxSHS0=P`^3rfKgKhHfAL(=weMMiiWIGjF0S3q#Y%=WcNUJ8MCsKCnf9LHq;!$Lpbc0a5!hAZGPp42UvW|ZT0WI{q`xDOorWe-@W>nV~)9E*WGqJYV zx;{sD0tK29qk7IMA+YkchHhM5o2oiTv{xf%TirkMSVm4H}m-%+f{7GyYIZsqmMtz z-=2Mf=bn0EB!XH~kD*7%W^=^j31aaIe*fS@tX#E<;o$*>hlh#9>?opPL@*+TU1=ii zq%K1f2sF@Cp{0Q)Z1t<_I=OsqWE{0=CmdPI8kJ

pIf3oQSDb0CPN1!S)LmQc+Ps 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 literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/I3ProB_thumbnail.png b/resources/profiles/Geeetech/I3ProB_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..f4f86aaf42b5adc52031deb058638f8b81ea9723 GIT binary patch literal 59698 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 IT|E2TYHIe6*mP-V8l0M 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 Z;uqekd^3|YP5A?ONQ%mdR14_`{11hV^5y^l literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/I3ProW_thumbnail.png b/resources/profiles/Geeetech/I3ProW_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..585784f112edccb318c493968198f7b145c4b928 GIT binary patch literal 50350 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 literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/MeCreator_thumbnail.png b/resources/profiles/Geeetech/MeCreator_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..aafb6ed5b7eb692b3751ee2770f0bf01abfda336 GIT binary patch literal 49215 zcmdR!^IIj(`|z`EcdC`Im*Y zojJhO%h4QQ?rCiS0pYp6m8F|VP4E0?M>{kXf_LQz0?lGQFtzSFuDUjtka%HImR+d4 zv5NgYn-??S?-za;%CpGlN2vdS5{pZS>bq4FXf%&~Vls+c`rrM`$KwYWgfsDc{cM?L zcwLg-Z`ghNUN-4*@b{y0_3I_z`Y;HzW3Kj!p7UzSXx&uez`8{)S0)n3{qWl5w;S z-9IwvX`@(D4k>CL<`t)(lh90=UXQ1rvz1z|LB>KeK1@1|g>?_kt=0|$jX6G3)i4u1 zBZ=MM>1!`q)ZB}R?=Jfm5pn<04EMr<;WU zTFkgWINsAjB_>`N`9q^kDV-6bm0SYBlS9>*Sz=_jcESq_9`?1bU^n^D7j@g^h^c0& zdijb&C6-_koh6$JP|Nyxc~k9db&7_rZCAyyMytW^%bI85w+q`)?s+HWXyEEImp4(&Ho}yI0l*=8z4`h|^J^vj>_O#6wp;;a$mN@OzH<)6o(ov7sqJjs%Io)u{6SjVte<4fV;o+RbH&F zQO%di=A8(3d;aVPi{!U3TYv1<9&9drtXviok)P#UG18AtQ{%y3S{H^Q|CD;ZL^@Tr zANi^X!i}J@YI}am|Ejy>-E^V&J!Px-d?$ZemW=-nB+1AIk^tAv%AT5^6^kxe>&gWG zQ(qYG+WVE*6zz%zKcb<&?`QZ+eL2etx3V@(~_|7^EE9y0PX6sk<|{| z$h6%SnJ)b+C8rmDA#xiJzBzxi>M0w6+Kn!~o<2NHut8UAlVP?+w1bqh73(oC!OxB9 zq~pWw^Qq}aJ;64+rv$;Ljyt)6jhx^(=22$67}Hqa%$^Cm3okekujgBb4=)d!h+)0= zrxSy9fdzR~Dvp-q59-vgH~l3>7gs<5d&7dPQDSDu^HDHA(a^hBO{}Kcnm2k(neI*6 z1hE58PT~*h^sK+4KRpCe-iL9|f;~LC{RA%ZsN~B7i0pN)v&>m`Vz`@F_d6(?yh^U^ ztD{u6)t`8Z zRSc+beUjWNpwKa8jVS&tzAVQC50!4B^2-qm?on`!WQ_9y9J~VTqNIB-ju#+vc?hie z23?C-*tI%cC_T+=2_}A75Om-Yy1_>&zD&?BZ;4w(%Je)gfuWHW?Xjf9@dbl3{@>V{$6wrCefqQU*O{Wn?)v3W1X>_)i`#3^Qw zg=r^|MON5lQ^Y<08+B1V*^q((o95OwP8QPB)@CXVGMw?+u`{hQ`n$XDMTgc~n*g#p zgSBhvcGYRjGM!SZ=0vOk@wpF#ujUp_Kk?m-{QX_qfCuV3{=TWe; z0_(&i@X}1XfVvbelC@Cxd+{=3hWtsGJIQea>g&lG5!xnQakeqZI5@+3K>dzl8Q?Zzf?(D{O zO4wu1^6_ZmHc7^9T9N#QVhcC5IA6@zaxF8B80*+~xS!ZGApc``_Nt8xrYwZ>gbDTc zBbT%x=4y)iv1D0s8*i2u=1a(SfoS57NeIBxmSzFtmU>-nN2JvnAp1m*o5UGVstGk{JKkQ`1$lf?~ z0o=B6G`79T)OnZv`M$x#k|`m%IRTe{u<2xStKCym2^x4;Ipj-Wl!*@i-ZWJ7N>ddN z$}&M%KUSt#jCqg4kFNWQHj-wHw&9=643F>(1-qqRKAO77vAOHU2j8j{4m;YY-|7R< ziFm1Pf;u|F)xuzYR8^Jl_vVv~qV37*O`wgTsCw+sMV%*wQmEZcjAd|8*Dsh|!j$<@ z(u=#6VrAai)BUwZaa#PYch^m)1|XUed&;p_h!M@#GkVQI9t%V4I7F%U=)0zR{B9ij zgf|rCkF}PV{?h;tLh|zvRqraqB&>}gd=glSj#JCRAn&qdYlTCAT0jjcJgsfiEe`mJ z8tz;8mh*;ZCa`Q%^n^%Pm~u&ZHzK>VVky*v4wDO$LUbhQCyrwuL^=tVYaO3A`v8R( zznpBeiVd{Vldd?_)$NO~j^RXtonXTo>yuC~E`7_DYqZZtjQ?4?-x1aUw}Q+sUQU?y zMjwADolFrVPggxObu&DanHnA+#=iHw{WOJwolZorW^?)C5yes!PZ;$w5aCjYfQj7K zQb%72RH-@$M){F%a;r+}BeN?B#248%tr?ksM>K<4K-yfKzlxvpIZS9QQ9*x6M|FM0 zLm>%e|DLQt(9jotDBNF<$3Q|Lg(akJR0lzsX-SS8Lp{nAO3sOz87;%G;-r%XPe$ny zZk5gKr8%%qfqRa7$@V;8ME9g>iIOFNLH2@oBu)4Fe8nIX&_`b`po+eG(u=)#WnR@x zw0oMMIiznzi-ppoq2)(*r$uo$K>7rDALD^JwAihORceD3e%VLDDe~{zZ_iJd_^oQk z;uHBQ>yqEKM|ubsEFWt|BsFbEIwiD~5>noKK9AE2B@agfn!7e{L{ZZ!&P;Hz|4p%YRqXE0*1>Z%|PY?Np)GaC8C?n)@TCz+jCLr~bGpDG#RBTWY) zM2b=JO6)($h9m6pf)HtJ>i!RPLgbb{zGRjb>J;E~)+)y2ndnL|4vHgrT{V}FKCo9b z6oQAK-lZr}vWtry@e8o69z#ggqaQMk??C zMz#ePb=MAp{**-#OSU&gJE=_Dl0LCSJnmM-PTyJSHF7$Kqwr^flla<$i?{MsxUVe< z^QNx0UeGTEGtl^a-|fvn2MpYjkW&gk*%2Y)sEhwnRz>fP}4jjfFxS{b^}Xk znFwMoEH|1kPyUP*N3=e*&lI_3gg%<15DUI2mwh(qpSfGtcW(gjsuPO9Ve!_Mm`VE5 zm`r3qG_h~>Y7#q1l8z1Krc)#r4Xen9^&>13%9unZN(pHJlO5UJ^#7`*az=RBAzH}CMslXQ?1AL5ayk224ASQ~y2$J~I z61q6XxDP5^Z5e@|_Om90%oa8mPj$OD!v*fBAt#bybgX6wuHk9iYS*W>P!n<$m5`%{ zeG!JKjnK_jmXwJ%#JxfJI#`JnIs{e^6GaKso3)D4KwSyHHN#LeP@2b zNha$oyB?Y@MQMqmKt#iyD3DB1=6UEyaOC=Rep}z}% z>o5OJ&@NJENNQbep4Q`HDGEFqCYBf{o+mexqOEWSL4SNaZZ6aQnMB+WFKmX(CdH#&S1lNV zlHbtzT~`CQSy(MdD^w8ub+8#ZBMK3%T$t`PVNr_4R5}#OP5&Dr6oc|^0JN#ZIb}JG zI1+rqrQf41M^*Ei=xeZrzB3L?yUm%AUc)2Z@8+z31D^7R-z*2ADV&iy2z6tNJ5KkQ zoV);@;cYQI6hSb(t=nh`*aS0c+bQpZqZF0TwSadbf}i$e#Swx7@}{FlEA{AshjfA{ zye>n!|7wg5I@!K6aZvR)>&dRM6u=lJoHov3nlmK)2^Zh$3DBjl77twVwizFs57;DA znU`X0mkFDqRg#gX$dmI*+%9$K!WJGtCu@Ma`GaIR7SA27(u2!A)c;cuuP?3?H9-RL z&Iuy7Lrz~VDWWoYo;dgJ0rv1)jdU%YV5)E<;f#~7< z(F-TLYAIa-PW>-~e~FY82&Dq|A>C*6&K?1-X`J-o;^x>*gs{Y#-hwbSw46}WS)J{W z^d}is4eDXNwB0d3FcWgDG8kzU_E~PVsol(Zh3BIxNgZF&_AXB$f4MJ)aF`Y9BoWo_ zmy$)90{WKczNMl#se9BC7{h1{-1jY(b7rgAPdUlN2J~H8*U{2DCJLlmvx;XyV9>~I ziuOf6%0OlmGhlrC9t`8Z{?pZyx_nn=-glHg&DD6tCUE^pSO z@o$`NMAfA`ihf0~}wn?d_=`tqB43e zw||W(f~S_beubT!Qw;V1!Q68MC(IC%qg(NBjfCdjNOnYxa~)9NgXzI_~^6vHu0Eg@DxG;oc7INN3M2%Q(uaHV4#DBthI4JqPP z`elK9zoHXo{g^eZ+xas$W5rxyR3T105h&%q`^%xHt9<$gGNzAovQue-MY*MXhd!hW z%2VIm04;}5sx+|4y*Tj!qWGJ0YM39-MG%K;p9u7fm-It*!SB1SK0}<7C=d$A)FEcO zEZgOPP0`)D`__*U^#Ok(xxfce3(g@B2g7agu?wS z0M|$g*8)#my*d{1FJH0bV<9xAuKl3G7B=CPT06Q1%EV>iPOgxShO2n5ST)(Xydm;{$dWTdTix}ntqOzIETx~{66 z#BV8_42ZAwW08SY)`78RY757-!O~KJVmr4;fBc4vG@2{U%XOO7HPVtE1v+b{B2y1J zc#31tfv_b+QJG%o$;E=RPx@uL{6oALV`jcc`-~#%+l^aV@FwBhc$S45O7q-{%D*GX z3J&RLE8w6Hj;Sw__-jsUAPT_|(tYI6>c}gl%%!2tn^NALIPd{9Ni^C~Bm<|8_?Pe| zOH@N5J&t>^s$*`&>D~6d#dyLM?sB{gllVV%*oQ(#X>8+}<+425v;f%%u2QDr9(xrt zQMto`8&$}P$@djzEl&LIet z#Yv)^??53q)QyM}p2dO0jikASW$dN35|{)&Z+P{nejSwtXEfY7R55Nj@*t+4SP9e8 zQu#SYbp;ZGk(mj3iO`)D@5}^*(g}IzOt7{OPN*((ez*f;@NhIl$tt} z0Es{!TGC}Cbn+~?wLefN&Tu9eg*J6Yg|nXe0``+cL1NUV7O#dpAu#79(>$2RwbgS4 z`2`<(he3TD&9G_E^ST+&k5&XSSpDaoVjYO)zdYoERl}oH;uHAdr@W2$qPU@1>PxIB zZGK*dB^I59`4&evm)DD7Cz~1RyvqeFtW;_7px76VEmR4}VwQg|>L2#;dr_0bYpU8h zE%brta;N8rBmmH@Uy51~bocxMnh$&IMtRqX734X@WlBxMOG`xa6-xYIs2F1zVj3txomL)MbwC@x3aQq$XN?=#$ypfJ5gO z&hLl)+@dmyUOox@k)zQobhr_)S25x!iW}uOg5Th&cR&%EdunZXn~HxmXn}?1ObA1v zw_=2w((HT1M42}lr+c`{2)j6eBN@RXj;MU`Tq;{`6~FAu6VxI3Au4>eg4<~QTH@Rz zM9x+r<1-fgDu;z-7m6l6A9!tuy)uiFL1{3A%H+KD299$v*+9s=*o#fl(ZD5^{(M|W z=Ep*NirD}g;dum2#f4I#rRe-w9ekR&x>lJ{-1lhzKgb#flTYM<5iYnW8kzZ8P} z4T}q|k%PS)HzYLq^~FqL#6)*5k4ph^kUO3L1SmVXPjTkH-sy!k$4@Gsoxero~P!qTY(w zi?E3PL0&BPWtCWZg~w5e7gPGp5cLPByF={AtEb~Hk1tci-GW#XP(w3KrPfFS!|fy1 z6E^t`Wgu+2@1m}oYP-Tm5u#T$;u!=X|11ItLo%oYd2IN(H?pXVkoM9|PWVSu-26j4 zz7aMnM!ue1Qk_)|jAc}bs$Pb!aaK;Y1HmoRds(tdCdpqW|fxefs**JIjUKa*<_JKvC z25xr@H)w>BMurXyIFs0Q9xW+d%;c;V8MdT&9)vgsi0kGuNH^0xl^|o1LG%+qRXAefw>!+1q+2`H>}p$lrYQ-EHB?SB|zKfoc@DmsuI z-@zLNMUq3yYX0u>*Jsj`U%E<&wPK~mVSn*oL>pL%i7pe3)gbK_mn`>+BS#mBu`IT6 zCqxT?n5#Z8HBwpJzFvwgihXy#BLEen=QBFBcIbtXar0#ks69I;pxBgu+Ns?{l>g^< zwLDod6R)mqc1|Us*7S;F3DO*c+{$;H&;^$l{NS(2!-LW7OWE|D6Pvw|L;&1IrgsKq zI*Tdiq7V<%1&W#I(9+70&K*TDS=VJUJKcA6tDkF`XcknZm+;#Bf(Z3C2YTS!r^VAK z$wlaHKf$&%bZZapQ;{~Z>gp5h2#+{+Y(bq=XeOb2ISq8hyL#0?{z;@~Y@(crfShy5 z3j`$Da(#|!pC)BIhlFdYzh%=Wm#6$b@edyTd4|V1fT5yV1~#8weCK6pO+zVP1YkLL z)ZZV!tXj$0q2T-@(V@{wO==d4eS}U>(z%0Gs22J{toKm{Y)(n+qOtv9ra|Y=!WGiJ zcpV%=c)otmZaM6o1y*XoSa6|jU3&YfttAc1N@W2|TseC~)wCGsE7DdFTw}{ZbnaL% z)(a%?V(iUw}tvwu`k75gbOzr2N;1CbcB?^aovY)IwkBsBy@`=3RGBB zDZ+6ZcQlFVN(>?vs*=ehK_2p-qkh)yy^ZHOgI9@zxY&JnnBOv}uod=Ngpd>nhhyW1 zCeUW5`Mlf|2_H>$_t;wrsFa8dL_t%Ded1#9_`W{u#8r1$g+hQov)-dY-?+hIv0JuE z(P3!;F9_u`r(%DtqoD77S)s&a+t(ZAJ=^tcU3IbouZ<`#Zh1T^L=(_Blnk>}i55$t zN9zC0Lrh5N@w=-5Vnz%KMa7v?7Fj{n_r*tEt%5q-qLvXLn{Wb>VZ2@=&*seDp2i0iw;2Z)^39A(a$Rqm`Pzcwrx@y6fK1!Y}7TS~>>z?Pk(^u7Et6WOuh`jM# z`xkOvoe@}TJ^O{N(JGgtZkBY_SKQN0QSeks0YVpsJYewGmO}nG#zVoVmyI-2G{VX^BRyav=l^6}mJ>_6 zW%u6M<}njLtm-|LUONO6Zyam!;fK^moz^qv*vC$euUyx_HRaQ;rR7HSc6*{V=G{GU;8 zKiVs%5I5e7uu7zhA;z9dzQS(vT~r05A?K>h??^A+tY@rw>Q6jb=qh&PPV_Im9Y9Jc z-UH;&4Xam483>J4$ykf25dO_UKScjlzmo6o8h(;}{w4n>@^?-`YU(C$LJC$9mfWlTKT06PT0%luPD0}U zfdT*F0NK6?Lb3y*BtwR3C8~^Q?iiS3$~jEoJ4NaZ2zc_k1wY}F&S^QVWmWY^U{`{I z$)kS4<6G*J>cNWLKo8E1$<0a0|1(sz!aV4664~DJ-t2-7`JF*8JwlLQUYZ*&J?Luj z^P#JdSmMSMi35wHS<9IXcIDO$9o_J{UvT1MGp~p?i-TYnGXk7mnl(r~xR6yk?3Kqm z8mXH4lI^KphKwcRtndC3 zsIjNuufA)Cn16$9NjTvUIV`D=U8 z2Wb2iX2osjZyo`kw2Jf8x_9$9cV4?6(cSdW4_i>5TxG4t!av9ZaNIyX&?F>KRIuX) z9$p@r-oL(bt)HHuNn)MP8wcm6{^K>^OuoxVLVW$N<#&}O{kMbYD68!P0fCJDzYYnJ znN9E?&jBGPDW>kZe$nO8Y_92c{H|+z>AF8vQ0Z{QkWwknR}c~}y2=}jy*gaLHlX-d z=)%GKh3{tFfy8_D4;UQMhlm{$-A6Nq0D~tkD_aOmsVp8pU7ot##D3mp>=b$818+0d z7bFO+lU@6mW;>nb*3WEvPjRjA^zeZhP71=ve*b?nd>)8DIP`sq+^+b4toXkTjgWoJ zNXsfz$|Z*A6#eL09wZ93grWISzFdWH#Ma7>K7TtP^6)0o^Stf-wJ~wk*0jxWLiV|} zo91`f>i=|jPrIEN=hM$Rh~zkpDT&$6N(qJy881?2P(3?8C?fxWCwp0>Z3E|eBLoHL z3$%)OfJr^JK03(%1%~E|J=Y^%f8FdvX;eui0{i)7s+JOKG`^QwGsHAiX3zlT_NnFe z%bZAn>mhiW@v6r$*hkH{&+Y1QbhOgR7#q=S*w&fb@xU=hj##JRSsRd#J+pNtRvF?! zktvQdU-J*v;e60AVbpSFsvH}yD$^^SOpS)=*(4uQ;J!Ia7qTt$qjZV}35TFy_O{>q z<<9TtEf)Wqo4tW6k!CRgFbp6R<5;9oZ0mVU38{ul#}=XhglC<}KmoJNDbG1h`4+<{c*RzIZP1D24}kg zw`k+`g=$nY#Fr+d8#TLTE6!UDaoS55<%E|lg%CIq8>hs0PuMIBF&GO3@GP&qMW>Y`THJV~QIoL?$O%G>x5|F;G!a>A5Za z?0K0_>wc(V@m>>p+sP4Anwr8R_j^f5T(DTw@h-vGM>Cyl6#&yzgSwNkY?-GlI7o?! z8U3GayQ>~eejF~Ki%`yUmZS`F5-BDON3af;1LYj2UzY(`Inp||1)y&>H4V$LMx=6y zcJ?402E~Of>&)YMP9cI3Cv98b7#D}leaC6z>_;i@-e|UTP7V`OlnS}}WhkR)3OTIe zTLH6{q-R?UAg=`{_gCxmUMlMeS3!6uG^oc7&-E`e!RTGIqZ{?&onUqRKUXI|8 zJ{4YUt+Bi)CC0b+>J~VP#vW$0YG`^4d6VoSmm24RStRO}I9hX$eOda1@GCbDnj{RU z5_R`q)x+rGrDflOW4+eCUsIw;Sb$4!1>*wy#O67N2qd};Msz0ng5k+KUyrkT-a&OA zfgpb#xR1=0?x%T~tM`pd?XUU4~8&&Du+xGez-(wt8wn zFWoz&)zbs*k10xsfmm3f5KVpeh#2hN`sFQ%<5Og{94Gytyp2DLU4A9;x&1c5s($VU z(ZwYR+?!#i%4b@Cd2M6ssJaX3_ig0jXrlO$fyH-C z-!pflBnmu+iyR#jT?mqDk9sQp)S{ zycA;b=3`9x>ALa4&$B}q?3iCe5u3HBtN5R>98c-FW0y>lO}E$5o(Xo0IOExFc6gi- zP@fOmM2jJ;2&IC(c+;4hR4bo$&`eQwZ`R3_5dxd+?nG51u3lZ?w$@vW5d!}cfrCbK znt9V{Q;xr`ZPPtwB&VX&^xnI09eI_I9P#nvZKRVznPW9-fBbTew&m*=tpTijKsqptJu9k`MMZB{jOH1=KA zw(WjeAOS0}E!HgvfY5Pp?6qCmV9%YkXv1~)Dj0@F`gXeE@b}=d?)OsF!xv_--;u4s zy^`VQzaka^#~Z*@Tj&jY?SH?G?hU!>R<<2H3azi%c01LzDqXz+{B@SO8V8$i5cWnV zmswQn+pBh&7|Rydj37T~{f#7t-4_J0m6t}@?#uSIi!oF~uh=Y_n?ExSnZ*vi6)l(F zPZZ9kL5z|c(CcmzIOpJW!dhyCpeql7aCi2+nTy z5Fc`43#0@0Va#)t3#z`({xa%LbC<78<49yzkmA`%P(`P$Rvg(9Z*fN~0ews+FH$J4eSwhR&MIW~}_xsNs?}C+22Bh&)aLhyg zedZDzW7A0|2gVwh+s{J?K?gisdmhL`)T5lC*(a9`U1Prz{Na+jA&qb|6J`8iV6%6V4VXLCM7?QVp5-2nsVc$3 zI_%hU5G<>0-L9X{aNmu-2GJV2I}B@eJ~@5yx#D2Y+*@&HJv=`{D_1SK``;zy2|i2I z`P=_q+OzfBz4~kTned+uPkm;2ov@;4swR0w#GZ5~{O!6a=Gh*N88+o{{AD`dV!3&d z^2ryBC!T-E@3v+&+b?GM$IY+m;8DOpfP?ZG7ffAZ1KMcei>_oIRv7F{SCN|oZ$o)1xp)VBUTE>yi6Kc+y&*DEm7Gd z2bv>9;LcI9%&rEdtN+@+m#JawR`3R;XzxS-$Y9$ zsZcVKL^P&zN@d|3NIvtZDOI0uB-Z}37!6v`vP6@T&lvL|ZoWa|iZ~#sd88?^EE=fP zsA6JfHlOeoAn>PfTQiffFS;JhCcWPA+PVjtnwtK1n=W^UV|hOB8#~)R3;tdQw>|$R zM0VclV~a5ZUn`h31Jg0mh->hTq1{!_7alr_c36!=}VOk-MBn zc6rWra-1$zB~KfjZpEelj5tlJXxEUvos4|?ouU4EX&Bxc2)k}Sh!x0fdtBbwisH6{ z*jwKYt@G_vBx|nuV;B9z!vG`}(xdgffbpvTFPy;FUP_hd8V;vSdKNS>+}jo2lXmU# z*wc88F*TV-4<=!iz@W(ym3gWbgoqO(PZxyrwm`Gf!w>`~B9W{Oj=ADbn}YY6VUn)&k|i4+tn=+;XsBAahl%s@Ue^laM0vXONoFofypv zbfjALnQ%$@;1U(o;_hH|b|eIlp*m6FIumAo`P3NH zsWIUp4%qc;S@L+@eN(i9k7p^4BZl6YF2*QFP3By9iW;H}6%UjyO7Q>h0n+{Op9$O@ z^L)+EY>azs_~g#)WPWc6 zo)CL#TRzE?YZp~M8k^0&fwqAmWqsyx5&l`0vrTceWzqsx?a!Bw}H2C()D&% zHJXR9RfQq5CP~tP@9xJ=si;)UZobtg}$vdNUB9t|Q4t>0sU8sZ^p`pkd#rQPsFyzUPI6 z6|Y6Yjm#4winOGd8vZn%EEh?Cf8UfWPi?lFFavfZ$c(Y0bO-h+j?0aBhKhCrP9K-b z$E1}E>2T<9kYwrk+|Cwt$$cN@TDLuRe91pQufIO8Uw61q=LU-0O+r)N2!?`O&jHEF8D+_UkUj#`={>KE zY8uyJZ0rOtrz(3MHe&^vCi)|D>nqOx#KzvN&`E})y*35Kt>YGg0h1etoxhGqM705# zGd+K#`nwINMqWITTLY4{Z=h5oYhIS6U~T!)@C(BhD5qC8x2OgDv4RLa_Vp5)M@5Hr zC*%KQsn_P3I{M72lb%898$&4@;rmB9ADwDSrzc!G?AUQ<+nLCL2inXhs3^*WXpuWB|TX?b*`5>)Tlwt2&z&<_eD&=*M+X^<@`F$inZbU=2q6qpTW6JUV=BaaV&bib8Sa27Hz1oF z@Ii7Uo}t$su84(4!(u5%g=^76#eRLX=B^6sNKkyk+7H-RXIZ8+Pkre%3%s6PMWCWO z_%~~7Fck>>&gb_)pP6F5{h8ZSpfV$Gv@dzLXsUEO@XHh1GB!^VNo=5aSM*KFKy7m@ zMn{DKrOEx$&!EvIWFqese!OWS`XTOia4F35j3e(5JMRUCmL+$w|vP) zz0x)xc!2G_#?2n>s10EgV-;6&$)DkNmFKktltUPZ|1Z;acUQj8nDI%q0gX@R2&{Fu zF%}gSJv^o$1VPwyjO-~$iwKp}+atBB6!{t3fm94GJl(lx^M9pFeC?k5?G7d>k;vgQ zGWs3DuSM`isbkUimeLQW@lsiFFKcD$OTq~U!goi?x<;~D^Q2@0HShj%zcAuNkiGeh0m{>Wqm#gh(GqR6n`;BoPO2}R%Eu=HJ5&vP) zEGH+2;gT_*vR*=!ZO=EPpqlW!~h-i$Zdq6ZRT~G>vt!;n8Xzl)I-fW}T zV(65fQK22FBErYAR~f9y-eL;>yy-;@k8U^x|8-W!$K#R#FY+a|e4OePVOxKGOq^bn zcfhE|R9oYGzDfP#3E#`jFFH*43*(pf9kPP&9%SVs9Hko_ik~__PE8OKkTdyb!^X!_ zti9TOkfGCkHj_{XuUMYGe%&>RFBj~Vf&nH86_22c)Y8)0U##HB7WB&06P~#l1soh4 zWH__&${PAdh zg7UrR`?WgVe>Yd{=!m()WDo+)`jbZ~_opYhrH%BZKTN>$R1sAOA+< z{)M;J*R!&6ae;g-ERItxnqKcgI`%V~j*kGz-x=lCuxlvI)4SE8V;4aJoCE20e1nk= zc*>FG-^oePPWi=6b+MA1lc17t>AYmkhU=J%`&GVUmA5L(0|I*as;4UF1R(<-Zk=8T zil-74c*TNfV#lMeR}~$KW%HeRtN7fHd1Iuj>=Ecs4`C;R(VYfR!^YP54a^b!&1mEN zUMch5`@t^{(0K*R)S`l9!D@r++juGk69{a(&!(p#morT@Ld}Iki26?H|mp8(< zoYHokK9(Now4L z+ESV)@5Rgeud(WNK3mj*UmswT<;?$<|>-^!& z%;e-ng+>*pj$&dls6s)RJ`fZuDxNP`d~IAj-e@yTsTzeL3>7#B2W~|94>`_;G*uCn z#lZ?)F4Z?U!kFKuua^$0FJ?zppTo*VSH+YSQ^;AY#(W(h*>(|1X~(6ZEyL(<@Z|+M zEREU|7a4jh=<~*5$HEe`dv^!nzu1wJQLHwED#I~Nv0$Ka^3JF4E}C*V^w^~AT?Ulga(HS~BIHv-Ljw&@j zfyRdv(IvIU_FS+FMl-cr*@lrS{rik5uyaJoH;(;TU7Yj5+5cSB%dP2yX< zPM4LoZ)w=?JN|d5UnaL>=Z0Tzb!SU6IlM*3#}>{qc>?W^4{OM+)3xf`|29wWH76B+ zP`U+!-iVfdqiX(YF_(;TwNEIxj3AAzPp4XDHp`l}I${+!O^VhjcYhk@OR4}aOUQ=B z8xQB?48TGaai!x~3pncAEw;IvA*;E3*X#6z%!Y$}tgwE%*cnRU*@6`t{I^H~p2;(> zU|)HX{xj4r_0|%t%H%cZBtNfOU2CJzG5r2{meYA4k=N_O#{W~V(>3B#Prgq-E?cQx zmH1oqFJp73(5zqd_uw=Zr+YV^o7(5jG@g$`r31F1<<7$SddV81f+XIQG8T+~Ct05y z0_gff?^o{#N`klM;m+D711{QjIA#W#1i?*k)zS>{ z?7@4KW$N^n-}{K@O0XefkQ5wZ`5KB^I)YQT;JmUr!O_tZhz(kIjt1Z4Zs!a=;kab7 zDT}VVuATR;U%yr0YMiXHQfSY(r|QR5+{lWck-(@<1>D25WcXjycx*@Fqu6 z#UEp{fHU(vhVN6&Y+@(hl;C{355%8VI>_Ej&H8mX&RCbPp9H})UXlE%B^(9qER5s^=))U+MNL}2oJ94ms zChGz>jJqd~t}Ovxwtm!i57xz=G--Q$X+)w&B)LL9F8!i;yZ!gbKIaJOsvqSA7%-F5 z`X=Un85tS(g8p~B;OV^nbzWqwoPiFe4FXR{aXG;wI(WXfKkymp=|&qZ_R%ph4cBMq z6_J$Iy!|(;4#Hn^&v(5t+hZ@OSYdUYvBB`a4j+c@Cs`()-ECq)NBjsA_iqH)8!f7I zQZOpHHg2)fMbcPhz$v1Sb`tI%)}^UBb|>e=L7f2R-;zgAwezAY%=d9Q2T@^61GUqT zKX(zUMiuq*0q5BfMh*@Mm!`S|r1x#7!^E#QcBC^UA>Ae=gbP-Sbk>}{2tS=6vh~?Q6DKV*^}du0)aUbNPn~M8i|~JRI{)= z#c0O(gYN`=@G+i(U8oh#v~+T%=<~X}g;O>0)?hce7xvY{97{9!d0t`LHQ*jv$5?IJ>XnC(9)aJfA<2Tvz$&a!STw?A-rC75m{-!rQ-We) zfI^|r~k;Lpq(f2l#g`=gdhq$Dl79O`K#&MI>Lj$_iKdX-^rHL5!WTYblA9t zND_o9;ABE$&ETmLOKTO-2{cYFFgE)(#W*kF5Hd=T26LTY@0+ zQBIMpEO7gw+o-P15+`eD7vK{h1D{f)f?dEa1S5Wd6}N^A{6S~BM4I|uls zGjrUnCaEq3G!9&kY1J7il(}~QAXQ`V(}18aBJcS`o@KSx;NxF<2rDwWq1stIXKh=; z6J41u>t6p#WkDN5>MTkHSkK4GCQ*`*;DhI5t)o#{CGabthA}2337V8rjZD`(8+^6~B0cwq#uon5=YC2}?c~a{s5l!03rGJMv@9 zn*up6pcn~Ckzg)AM4(1#B^6qB5qym?9h9b5p6~g-8{Yl5_kB%8V)El@8S$^d~S?|i^#^867B z#bKl##E%w{%?Rld#>Q&QUL5Agi8F*{!>jim;7|VkVOmT3P{t?fAI9$+!sZJ2eue5< zKe4PLjK-N|yr=|3csY+S%w+-K3u@b?lv%oZL(5ed1X+EB(HKcq+uf+*N)a|cgk4%9 zEXSxqAH$>9keW5t7LOrJ6O)ACBASUMbv0T^g;Hqn!z#u$F&H9qt;Fe zK`TyCN+6Yww2-zpWpNseusE3|FB+{TtCbpqqhq9Xi^wUGWR^epyBt4RYVtEbKENOS z?g-b3J{C%=Tw1ai*Mk00+<3y4nHmqDJjZW+-(3u?&a+Yuxp?dZ@0)uUg~6??ez3}k zbMNQmbdA1&9pqJ>Rx5_eMM~w6rUoT)cwT@&V%gl|nAM7BRd}A~;ro8KP~TS`tyT-4 zl)YO=IkW1s@1}31zc$V1AAT>(y2YVezn@)K+=FT?v9@@Om6^v$t49%Tg>Bmp^UW{+ zW4%e?B_Ucugp>-oedKhE^*MSk!1-p1s`X}<8qhgn=)awaej{qq{#)e^baf)pdtNg?(BR=xUhxov|-iJ#qyIn$6M^tK-mD&PhBLnmg z<@vw|KJY7t4($EFiRX_$H!?m}%SQ#GD99>MG8sX&lhxwU=gwYJ2qL0_{F(;soD(1W zr>CE}@q7O0>dNT`a^*fM=`%F_+t|6|E=uJBg`8w~d^?A)*uhBu6i1Id2xyE^_>sex z0m?{>ZV*NR(pj|4Qn;mZKgL-G`inT{IClJbaE3Tdh~p;CXiCLA*IsuWtE+1)FE3Lp z^wCONI3Sk~(an_97=-U=G#XfKs8lK#>k%nUh+^I!V8B%Pi+41*{afn%;A^%~d;AhF zy*R@6#REJ^of{*M8;%D&n`>fk8ssJOm-xU#PjO`DPFjKEtR6j+Jlh#Bv@rxyVYS0^ielvWf&cUd-uqBS5Gx#A9n4!(ksxo5fX#D|dPIKTBfZ|2sU@1zus^3;i& zxZ^jZiS;>K2EpVw zd0uh*Zlcolyz{;@oILY9k<8OdDmWtk&S?DLGUNS|{Kl{R8ee$qDL(y~kKmPa;Dc_Y z^bZWsN>X-h-O6{o`g`$m5l=q;1lzZav2)v2;`oE$B+3)`p~n-CJ;9xK-ooo%_d1?= z=2<@cu}=|&I`e$aWIHNJ58sPetJi2WYZwP<9Mf#hGCDAXmrIDWrW_QBa)yUKFPS{E zz}46H^W=F$R6WO!y?zHHI~x4bdlGgHNZu6f=F4-Ju-9D6{&0Xws2Lsixprs^Hy+%{ zQ2!QkQf7UUszELc`N(~r=DG9JxIQolJmH9&4O*=hxk8aJ3O4M~0Zuy%25U1(~Ul?s+5e!YRJ^ zWR06{mi+in{s2Gwb8q2;@BaX2Z@V5PJig_-zYB-s#OYJSaSN?A)oK;@FEuWH-IPOF zL>LlR*2sAtwMIfJB_@=FVL%`i!V+)%%J>xr9FPK)_TxF=4_|ob#~yo3Ei5bq)3Y-J z7tWo%>cWK!uRV9+><`6_dg!!cW^s*bJ*E(<+h20^%{n(6(zk636Q$kk-c{zxL)&P& zB5!}sF@F1ZA5bIPwlOqPpp^58mzo@T<~WHQW!Ijakk(1o1VUN7+z9=pA*D`BXw#FYmRb7ArlcfRVID3;5V%Y96r zzsyrdpJH%mjACgRrF`-tp;4>SH#A6`G%-4BVDN;aT3f-mg#L1gTCG89G+rUVwiKc^ zN2A~|kaKJeET?A#je$WXb_{SNl{|TNhC>&&b6a1?U2_Y}stYVnS~Pl7Z@oY;QpsiG5`CY;gz@aQLk4ycxW##|E6!_kACM5Ir02?_UxMAum9}NNK;2X zpQX?{-7PPUayUntH1VZl|HL+KzU!r&yl|06zVtY)BxZ21pA%=0Q`98{fEEsSmC)7r)#Nhv2%1x)v7Vio_LbDIm>6iG{djF^#NM*M{(51mCLji zENhEHtfd~&^`o3$G(^!>qWl9vRX@clw#<2w+ckMInu%S$B97DGcr?A^JSshL^MPhP-R9)f!v3Y~dxh+`>=%#82>r&p*U3{PLUebA>Kn zHpZb{d#^te5an|;n((pDJkN47Vc1Vd7AEO0NKQ7US*abSZ|m*EYmd`hdYYhEM$GR= zEq^a7efwA~o~6IAm9uAONop4u+j=wSE`E_u-~UM#mKRuBnB#x`%6U#4JI49f&PJr>3JXDli)mZQNYaQN%rpE;|^YZm?)o*2g`kU zfsYj4La|tUU}$jgQn6S(A4So{a$jF#U|?XbR4OIqVqY^~2z0Ix>3lwKq9Esl5H@S) zQtrmvU*hdPe3)8o&A)Q{wr;(MbxyqZGi&zf(iaFPK1*4DoJM7dm3l~!F0ht1`1B(S zM5QYzhB33xJxIMZLz33;l9=)GVSehTUXQL^q#8GQ>WL%xo`*u=w4r5FreL=XfluU0tn^igJ~rnAk!TQPAQQyLy*aI~MBuDOn5&pyfVlV^BphmZ0imh02V z%0ku{q2p}3G$FCtF+V%aw|>(rnb@;~zrXLp99uY!@&e*Ct63Qy9A$KLjD5SdGkw0r zQ}GJ-lye-OJ*e5E(-YN|NG7S=5PKs2p?y3`Zpi?TSj+mXSCeM<;f|I9b2GpaEYM2 zM&(q(@YpVfbE6!4@+n-Z@p5AnqHVO&W$LpJlgkw_L{t}^;l^*hgFpPew_xLh`T7d4 z`OepH=4{ILi4p3nS>|qeX^ANGsn_dxo=3geV197{tRn~l@==b&rucb}RwL%hJ-hji zZ+R7?Pe0AkqtEe~FU{c>3XJXA!^FfOA@KOaPok8E#<0A&#FmjktVz&mLYNP5riFBh zNcw~(Vei&))UE?~VL-L{Jb`TTx-?HxJ$T_Dy7_QEG(_DWqc0ZD)7{kv&4-RZrJ}4_Dnp( zLr?z?cHOiU8ScZz(_A|LJi5Hr){!jD>N3igI44PUjPHe%%Vl=#*umbtdtbbV7FHsI zfOD7UNYW>1>X^$j3k(mB<1i@SCuwFLWo2=RTBD9971BWz<*^&K1``{00SSVjU6JL` ziDr6wo-^mpqtmR(HEphuYS79f@_m%EAQDn#D2Q>QGNiJ|>gp<5w3t6N%jn=DrENaR zO2V0`Gb}D=D&p$uD#B(NGU-WlVhH_!)Fj!> zk^<@ZfTR&8Sm8*Ml%f6s21zN6IgFo~w&Qhe#qWczb?LC|iZ$f^&uPI>0pquh1Z zT^u}o6>F<2oH>1pzQNHWw`Q#Tr&5hUZXIFWcxo6(R*4y4jDH!Bq_kD!1!2|5rKZ0|PFz^rp z{3sv{OIcf8tf^EgG@H$T1%qzyp5#S&&Rm|S+FB#Z7bxV*2z* zZ+vp<@}Xw4*}uBFO0C-P;$}*%RwIsMn$2c+Ba=9eNllA5jzM_cP8B5sv`Gl_14Pcz zY9?3%aUdb~AkMR3RtcI-@?M@oUkRxuP}LTfCZA>B{sYu<0jp~ZW&k%!inT%mxrj%KqC*5OGXi^2D^_jQus z1wMiFaS~QnR;VVL16Lj5spH34oL^vUWDC+7YDtAlXU-s-Rj$5zKMS+-SkGs!vdZ-A z6jxt$fMOn+X`Q&KDfLGT?il16A$c}wQVvI1>CbUfz0MmOEzVXG=CRx+N_-$!W->p( zwnj=dGoihio4kDD{!j7nBafnls7uQ^?ekI)yb7L5z?g%J_WjA3uv}716P#JW`~TYm&1~C=C%6%M6Wc!pboI zo*OxT;uy77lR{rV@%(8LeV$e@Ono7tHPm2ycz_^?(8gh%#v}&MlLXxfC~#lL&KzIU zppA4{H?&j)`5gVeq!8rsJxS~=mDN>lzwUZ|@JD|5wg1v_;y4v?9HSE>lOz$fdR^9P zHNVkldaG-z!CJGDYphkmN~Kz=){_2aOBdEwtJ_u=R>v+a&3${?D%{js(}Y2dx}ImI zGDsu2M0G00(|M|`)2Ps=9!J=QBJc;1-T*=@(nuQU#Gz!7{{B&Fl}R3d=1cAF_7b^) ztkcBU6e|_h%QlXYK?php3&N@Pz7YcatXI)mh4MVSV#G&3bw4|wd5ZCJA6H(t6K5Li z+_#597_hdsOyV5*J=?hI8i$UvJ)c{q3XM60Y4GDe_}%oC3X~gV)If_YMPg8#b-jvM*2IA<;Ob5lG)+ZMG9sv%1Emi!G{2nW0jF z=@T;;v7ee=Mm3)ytTl1&GBVesUQ1~-8ibK#ZgvGHLaNKN#HmLEJ9fV-|KcQd@Y2b@47qJZfGw5deo37 zo<8;)4}AJjeZ~G8_?CMQM)m62*#CUz#fzW%)Nv*X4{`LV56~AC7@FA2YU+ z12Sn#dLDg+VJ^;2GnC6yDwg@uv9laIJIVel_VJ(I_@gvhO=jmNag8Rzw7Y)HFr=`3 zOV;WX1Odm_PQlX&56%p5(w^t;$}xWNRD~It*dzf#;KJ_x?4SD_K8hyLwVUyXiIG?HKCr$2Le3o1>=E{Ayar*v;ICSspsD(ex`7iw`Qs2+&!Wot>R}j`?YT;y?d`TCK@fFw>z#I- zIFA2KcV)l%x~oje+Rr?7_Q-s(n2$%s$LibnZlT$KGp=+4S6q1m6JtABT9~F@t)avq zD%^$4?Vyn=R#sMNrA55_7|V+lUipe!IP#^Zc*|RUm9^Dn;%1dby-KSQ6E_oDjV6s+ zowSvb=#;d*g~I0Dfqaz8s=^|#fU+>wKa5T-^Q)^YS7XjxnB?iBXJ{G4%*+x~mu6U9 zsI$1Z!s6;O)uhgnUZTY+t9FSRHJYpQ{D0KFd6;GARo?sihQ0UMXRN8as=8a<>ekSb ztkJS%Nwy>pvM~uJCKmz(FouVl2NE)p05>Ed+{-nWJh|LUfSBaQcH$7m1dNRbEQ9cb ztjUsWNiC_RR!`N{HCLT+Pv7_5KfZlVovLoxg0v;GpGQx(x~r?sIeYE(t@W;Vz3<|= zRb0{ICzs(vFRqegDIe|jc#Bo6U49iGxZ+A$`wt=F8dF+vnQE}u&~!UJ@3K&h5uw*G zkxCJSAv)BaZ(XUB_tb#%;x9v`(qX{Ja);Aei!&L{fBbaPWaQ%VT zFo&gW`d}(dOde&RW|^J8oWlq9GPiF6Qp>`^0)?%5;gsCa8}v!C6m)=-f0kLyzQ>Hu(W!Lm8DhclQCa@<{VqA5JnNAR!8bd<_{d@wuzIx@qy2A!&b)Uui1;4 zIlvD-e2kAb;s0&zV|GyyZget{}JZ&X3e?IFuDio&8rNFL-P-9IA*rW8sa z$w^?5LV0-#DKLfK{x-%UobZ|`QlVS{gkUS!!XZ?Klm%PGfHz+MdKwecELp?Bs-RYL zw5$8k&2Qt>=>)U2jLkO?d5+XoDz$lRcmPqP)JzT~Ct9k4AgmBo1Vt!lcaoP7`23$9 ztdtC_5>~M;Lk?9fOW%`M;=19;^v35Zjz4@feE0wTCoAu+rCp-6MOp_mH(YiZ`y2b% zbAE=Sm#xuHQl5F{qYToIGc$3BeMhh3D~~@y|MX|klSlaPA1ip~+2b6&t~Jui8>9nD z=?z>dsVhnytc$(FEXz=V#uRme$f8t$bSb?~1g62_W(TJYx7~CjTgzwB-3{8OpJ2Va zNdKH=^+Zl`c8SEq6j^|d>tyCd{>J)#-u;eQ?!Uj!?*;*HnYjjgewBaI6ntc5iy(P| zbY_;P&jm!47BBRdAUVSW_kDtujRA2G5(o!Lf+_s^oK%c9w@p@zT(H70^kOg!Ri*3> z-8pN$ltW>ymo5txerF{mH#KUrR}h&NAN{jOx$Lj~9~?aR4$dzvl4}dKkm*Bjp=e)6 zcjF0UzJaJzsm|Yxs$I#wZ-}{iqR;R3d(@MR8(woG3(w!eQ%`>h9e{BP{*dQkv zoB^Q-suS!#JjedI0fVhG2w^c<&eY^yUUSW@JpcUDI1;q>OVEGOD&S?59HrbGL&Z>4 zcKFsiD7jb8Yw_x9Zu+GUfAQ@5T)Iea^E^R!gHEx<+MvnW#saUuI$(8ajW0j)EY<1+ zNjK--H{V8W<^WR@4T@xdaF&^wIpRhW=^(DxMhZR6dWFtbn>;sVJ!wbEPeXkVsXT^0 zk~R|{Wazb!;`@h^XtXOBNeRI83Q=r4Axd$oT>S_r}b zoDGqppp&ih+B;vv-+lXQ2+|e0c9uVSVS{cGQ3*0!AW54Oo~l|1YGD=8m*lobx^QozQH6nv!g1*nvgN~J;=dT*IXNkSc^lFN)UUrCwr*7ojxro-2 ztNiH$o6MOu!enGogYyd~NmnF){cnCJ?|j?c*g*#=p_^(yG_iehVbC%pQsDAFSr}o9 z+z+ODJ@VX(nhy<*MglKmnR%$7WS#TgddiR)g&;yZpXs~pHL^h;)l;l=QeJq{u`<|X zYior(?O}QeMQ0OPBoz4`3~gkw!TM^-xzlI4;jS9_+6LJmBM$~NS|RnOq}|)3QmrsC zF+mve7w*qqb`9-DmJJqXOT$Q^UXg}yczxmvoiD3=oouj)GLz)l7CLb-P|O~n(9T2FY_>D$aDug;93Z>t8mXOw$I5;_to^0cuI?WZ4=E!ReU1w-% za9PT+qR+u#j+$+A?v^Q@oxPfmi&@UBOd>w~G{5nCg2i>oZMR&*i;tb);Nb?p`;q(j z;0J$)#~=C}Lf?g|&f!$X z9vJdygG?BLG==_oGB<~%JDw<+001BWNkl)lsz$DNn)A3yv_Y;GAO8Qo4!eOfbkCg+O}o42?4k7lby zQFw=3J1#z6qI^9zYT!ytVQ!{rU>yA6_X)wRH&c{FXATOMJ zjvyZ3wkj;14JpEPi1xE*>U!#}m^|I&d=gThy@sf93tJlx&}+XyC^bqclC+PIk}%ZR zEJq5BlcfcQ4nQame+80C7@>m-IuJ-5v1e)zYV9O{{@~}xf9UNTdB+-4O9evAQ^XNY zPtcm1=XKAm^WaL%^X&;bs~u|LEH_+z9Z97i4GZRpXa<7C7au}bkFd0|#M}Sck8$-i zS99e0H?g{;(P5SK?h=oD_KV#6wtEP;nPiZ$zusiScuB7;OMIXzNj|4W@*(lX=V`8j6jD= z*c6Hjpp)Hd>$@GWF7@?C_kH2~3&$Sho?B;FXP$+#kmzYPy8$Y0a>Y?erC8;G$DU$g zVb!blh=@S>Rr_YEK_%$nY@2?2i!@z9>HsMsY|$aN8wio(EEty)1PbB2dcTT1xF5)} zmM&F2%`lxiZxta>NaqlyV5&L6GcTOreZT$y|L}VQ8tWTKRb|8Uu^9}KhdGz!+H1W_QVZz>S*_t39M#MtzdJ|X8-;xDe@zTe3DkIX&uT@+H%?4?Ywa8 ze%^G~>seUX;1i$t6hdf}uHalssCDUWqR>)}HntIhFs{HZ)20jZpz{LdLI`pr5Yi#F zz{m=&a~`>P8ZkA6oav(~HPXx=qkx&quV%XSMs%=;tZ|Tmu94^zt8xk(5J*8O97#RtTn=yVPud`>*>Nj62_~8G3=iause)SW7 z@`bDZ^!_KFeg4D-34*iB%Pc)xFgamK^G%efFf%#D++Ing(k66OjvfeE-gt~WwZzVV z74(ZOuD#+Yi)Wg=u(5&+1ZkFY!ws)NDaGTDe}yQnAeE$WmZUcT5g>%5R;v=~5UV`A zCxt)<-kKuFEjsA)!H+%3AABa^Emu#|oH>Q=H+a*593?BXo74QqkN+`^{YME~icZH+ znR=Y>{GR`Xhrjqmj(_=ns$mOb`zYH(R%Z!gOOd8nH^t1PxI}1*qCiOT^+5pPN733AR3b;_G=-JOWRT86Q~!z(!@eBG@#{P{DFJ#zQTa(mC^*BxH@<1c*a#B}WxE9w-n zn;-CH8ukggVKCb;DR~_6>qh6<$N$S--pj%iMlZhA? zKryJ`IzCH#rh=pb^xFoF(gb>2$WdqX34aXk%qgo_p)*5U*NfN)CqnYo z6^;Z~D+p}NeII`eiKEl@)Z=O;Vq;^2TCE1o(o4G|q4i4(+l|>cjP#Yu7HPM;(KqV4 z>yA6V{onuUuWf$j@h{y4JguZb$c(*>kZLpMn%BIZ*lM0TbCSXuqOit9t%4(CV{L=> z;4D%%P-2q)pa(Lim$$JdT`WzK6+~8IB)6&ZCb$iYYRbm0lw{PiTfQMq~_}AT1R2xQDL5Aj_%h3G&?X%fIpG zJn(FfhaNu9mLi-$@$v#_yjD9bt*BcNjN#Zhu@j;3V$z4FCDi|k-RTYyL z7y)q{6F32Aic&}0x&l`kY&s#(O74&3=g*- zaaOT+c9u|k{RyN$oq|Yn@Zdpuy*``mQ#}9t^Bg{Wn6qcjkf#aVK|-SzF|&6sg)A`n z03{60hG0MoP;o}B+2V!gyFB^SA5(3%m~6$&OiVE~?N`?3_8(-rR;Mx5Ig2zU`w)qh7PPlSR`FiG`s{hMidbo{lJqpjR!OWzA&_|4VehgaM(RvT zYrTdZD6nO~X=EiTN^BS^>DR}6>#{`Y>@cmLSm|CuuY zvwIIPF|(Ivo;l8--R0_|S9+h7UYDhn^VDU9X0y)Z#2z-=9Zo&}0%05?R76y%Vu}PQ z1(m3Q(t`DsO?rK=uaV?^oQn`>Oj`I_v`E?9+~nNZ1>#1NrKKg#oH;WREeyht-XLdl zYmGSe!w0X=BC!|*A#o%Sp<{BcNjT7KE-%yTuJXp)Z$k*jkNoK0;cahuGf%&GlK=KQ zzs=0d46W%JCr_Q?sjogwzn>9S0-~ToJ+9ClL>#&D5c~Jev2fyX!mQ0?D`KjyX~l}H z?^s{mLfwiJkVi^Y;Jf&cqTXIPP+KxG*j+jrQAQm`b zUlAPojkn)=_MUfsck%yy@V8p?GZUR=b1zeS=P7_Eo_?0s-|#x-5AI=Ob~3-mQ8tb`_QFJ35^nhY+$HXt7L^C$#UB39a>EZw!mU=xue_ln>F53%iCqFudg#T zJ>lJ72Wup`B-m`zXzV8`I^Ih=GFU5+%0M0yswx|uMfUHXl<50scBT|NFCAXwRzXyxEGPY3zG@& z`P<*YLyw+d-{B|eX91Jv&+|-?qf3;-7#|dI9FL56hHhRLaEeEm9Ucmh0w*LCmcm+u zEil5+?RSW(HKYmvG4elA2rwngiKTFX@AjPcbyPxPvXZVUl;>=i!i%LN5z_gRR^Xjx zi%ZDm7&rSFr<0Dxh^67=D{=j;zwxdg{k`A)AHVaz{_yv{^TVI|_#+E(@VZvB$-aI2 zkbz{-@3UuSii+OL(%KqR6B8ph+OV`o&Q0MPJ!i4f8w*)ijNY5p5mE&>VF^`0Q6wdQ zLleXSNtzP`0ek1?$&-Y^pvS=@huJ%SfQ@#Cezyn@9uYbcG z{P>UmU263Smd>9eOS)Wp)s?(>;v~O)_9RCxzm99KxylQR3&FKB^W6H{H&AUgs5e>! zLZa#|x@nJebpbmVufBMh={eOGgTi*W99{uC{?r+sv+<4;@QBYxJZJ936oSI_)!NbhV&66a_ zXc55_nI9A>NYcdD$WoGL-h$5GtnH)CSddbqtUs!xl&mZ+aoepovVU)j4}IW+TzB0y z{N5jZoavbv{;yyBxBSx2|2*$~&)=p9V*bm2`5;rx35qPCumxF>@=O2EFC&EHjc>ji zvXn!Y&jYZsvc_$IlP-mGg@vy*|xmlWw;=ayT1Ck0=+SlO!PwJjXms zQ*ONe1|E6j5v+h_D=7IScIbU_f%3qm3+S;GtMLYKN7gp4OdTD?dhn@F{>dBu?mzj- z2OoR-@l8<(2o#%}n*=JPy}p5!ih*;;G^1_|ITnZXTQwyeQ8);L(7VcJ3BuXYXnThr zwR1SsHlL;N7R!rgPO@}P2TxouN6=VrFIrvH?er9%Xs)Je|!BhYw%D(ZkpABy3Lbxi39|)sm`otS!F4SH2>6VPTcb2rA7wMik8MnPO#05e16H z#RU)BAu)wTs;__VB;o>J_8EI=+p~r>$UNRF4%PV!g^IPBc&>wyJ)7SpO|M|XS zZ@%+Ra_3Fe*H=%|+1MnCL&9o}wdD;a_Ri64HVLB$O2toSEG93=O+lbEK@gEAxwi)% zTEOAglfd(!h4#*~X^~T_*LmjHDV}`tDQuSWC-?s;HfnO!)z|U-bI+iZ;>_ZCc=$`K zEu8oKV-*nUh{P5YCMQsuqR0t^VBy76UNa8O{LEf%dHoysgFpO3&YW2wNxRhJ23m(i zwJJ_|+U{o3V`6?UN8k7kPQQ4T`=9CX`9FP@q|jVBa~0Rky#^-*6OD-3=_zI=_Y#FM z!bu_>5rq{TmckTh@fX8+hZ11`6B83mPw(+`fh5^MA{y_xJPfBtFrkz_!OYFgQLi=V z_xtFewC=NJl%a?2T0=g^%elVpSLt0f)y{D^yGT2)%=K;Wc*irp_zOSxxq73*lTSW5 z6!K%wo;@_{Eqd#l6oZuKk3GwQ*?GSGUGL)7TW_V+Y7qnht?5Z7r>D?blcuRB7AXzR zY-69+fh#=;%Yjm;G(}-33=DG1>PDAmpLvm!&ppjdvre@VlN654cAqDo_zEBUSgkHbP-+cFXuz&w$6vq3K1j;+QR;n>FjL33>5f&8Wa@q|RVXLAtTU zOlyk2`R;dd=+GW=lh92I4qb7WH{bI{CTk(K7=Y6xNj3_K!da{{Sm)3|;7_5iQ!-l0 ze_Q&d=O!c1eZyI=*AZHcT&l*s;Y-*6S^f-bw$YHid-u|snxrr}D$t{e^JtfGjFeQC z99x&HDU<^5$>+vAhsUU;-{{fz#jcg5^%u7`dv|YacIoze)M_<~%xAxTzfV|+IKQ|+ znx@q2Rg9aYUa!+?wJ^?+=Q%}^Qlts8{6Jkfj2OX0(&3EfYghwjkP=8e(iW*VYJ^hq z`TIZ1V~;+LkO7V61W!Nx3{!h%*tc&V8yg$G@k;vCTXj!(vX--F&(i61sMlLw09|Wz z5O~~MNzW&-3adh@L5Q|svYevG{ALVQ(llY|{CSFgpQA@E=h$&Wx1Z4I^l%0ORU<1> zoHGXo8xl6L(dl}3!HPEOIC7>-Y6Fq?EY)aD<06bdh@4qll@?xJ0=?~zsMR_ zN%MrNsCWX7GgK-eD{BMRH#cdw+Xx}(CkaWCuy4LQacHHWE_@2j`x$*B^7$3aWTJo~q_G^A}^Z*U_ zRd*%U^-B`a!__PQJ2_%<4DAYDt?M0cf7|(weB>iP^5~H{77(W}W_42b1Ms1-WrF^w25Qv*?8LTPi{1 zwKJq+WW=tNq#{BnHBizt^~bF($W4ycAzGFVn3N2<0~QyLF}Hso6a}?f#Qy!)ar(rI zI9uR^*L54W1y(X5iXwt)L?x~gRVsv)5T_M!9AkvQTEIAhz^{`j;avzoVlDnZGu&Dq z;}|Xr!<7_3n4S`vbrS{xbjeDd6qj@{atWhac9jz3FBu zg#j$q#4XJ8HEWlarHJD~YNxv$M0bH``ca(Mltf+}^Ct3q(1c$cq$b6;gRI znZ?CLzWAjFm~6ICQjq5<^Yi;@uY2*AJWWQ2;C8PfQ9(c$MYN_S*)uakT(2R6h>7Vb z!b(J%_9#qB97oja4T2yb&oZwz^8jF^5d62K@qU@!-ntP`CSO4l? z@TNQNWNLbv_4Re65TlNLc+}>3&hg{NsaC73t#&wh`ZN<06D0ivi@;jLV9+0VVmmC> z7^HVQ^TA$ZggT%ShjhDLk8i7x!NAh(4Mx6zeyV3ie%VrJbQq#55fjtXOioS`1_2mL zKkLw_dpovjqfVt#p%%wPk>7V5D#u1qM5EE5TCMuAx5)_!P*PFk#=pj~+IbvR7$qww z{YFpeDqUpxj-Vd$FGR@^Daw6JTRLlvKP*G(3+o(0ZUYR?+Oo`3W9m&}_#m_|&FFiK z0Pad_ieW&H7ApUW2K3aPy-yaox%qRS{Q^;3@r$md`MQ5!-V{g(!Leh{a`NP9Zhym@ zn4g{HfrlR?Pyv*I=NKNV8dQ12TkBbGv9Q4}#K43UOPta$U?_i*ymIsWU1{~J*hlV&}?04pQH zP*aU#q*5e#MzvZQ%dBdYVRvBgcAKX&lx*-pZp)L%`Sq=_7#L>X@jwT$qaL;;@-bXK zHpbvaNSV8!ZXYX!dY2@iU#gtg)_{|*N>g|#uC&M>!Ev+KzcysW5F;+OH@$% z47c$_p#n`D$Apn)VqyX(;L%4PW%1lu|H6U_E>D=7pB~k}r%#;%p{UkE-vnCaYx7}A z5e6JSe3)KuPzs<+?5S;s#*B!lv7Xpn<2{uV1X$zv<^o{sI?YrQV*#K_^F@z zXA~4n&P<_%U}J5aR=vgKWQ%sY&0vuFkc&W@Y_btyGzwo}krg5m#!&)hY-B#J7WUtVH$b(J6rapjH8^ORb{Yua_YT{gBh>2|yHdILKB z0co1Ev9ZCGS6|D~Yph|mX^~@g4MT(wr2PR` zTz;5+vvc(O{W2395O$>SI^HM_;lJ@FaQAD_S`RKshTg&95ZheYi`CeF=4chk|ZN5 z%;;tbV<@cQ`+ng25keAHV(M{(wu;GClUl9DO*h>{dvlAge)X%^ykLHQp2>+>!b(V3 z38>a8OixYVtjDPHG$D6jZAMX1I42n-8NGfVr!;9cAj#}lx#2UP)*4eaqZ46-FTcbo zyaNyzW5A6MSyT{ge_i3<^N}M*SXx@*si&S|@BG{-R)*zVpu*Aj7;VRt>tRKS7VTnr zUYZ)(SwANAyM#WRRe6M|KznU6#9x^pe(0fxbhq2Du5GpVoqGPofBJX+-alk+ZmyhA zc}%q^wr{v|4jqMrN{@I7UJlJ~Sm-z?v#PI~rSyDW=L~tCjcAcktx6~D@z^7ebLSgw zXOQ$s+X>Y;WOZ$gH{JDSmX?+{_Uv=qaKp{i>vhuHu(7d5zhgP})#o@nagOV*yPg9F z4p6CtC?QDt12UIV=#YJfuAw()ra644Flv4dm zjzhnkX7QWh`tp|_QJr2t-dNw-v$DQ+&BkW?TRNT2-)pzq`a{3*TV%#~!NG|JhYw#) zS`_3(L9g8|ONbm}EY-MzREj)FFy#bHO10xN$@)2&&M;ZN!&aD59UmDG1q#9oB> ztj~-Z6;;^kXT*(Zj-Om03an{~j<0p!cf)m~ z#!*UwAoLKZlr$Q?W|z|U5>jqs+QTuo*>%cWE`$!1Qt2fL=$ERWFZv|Eg4dTGd{}h{ z{d&9Iy`tOg-d3c^d$X*#HBD3fnLqoYuQ!b)Epj@80li)y83aT^5Nd_84uoZSX^E)f z&D$%Lm|m|(5QNmLp(m#!MvaTmUZY}&kGgW-&g6zL4AEL)%6d>KJvz;tv|g6Wcn(FL zrdX3gpmx-bo^|HY3I93*T%gez=rBYmL7t`*MUJzj+^-Y}4b`}TM3LLvO8}=ijsg)@ zh=PbpsF|Fa7#IDU)v~Y&QhZUx{G;>JwkNvy-N8O`ZFpB+U+*qR@-$8(!l$shZvhTnFbRao(<`kXfbynBcDTIYVMu9{+$d$pFd?e!Tmq`7uLtSWtMV4!5fes0z zLm@$rPkXn5UzZ{hIpPG z*3V^)UcT1sk_7ZiZGF2Tr}7oZ&<}t1bDtH)>L9ET1cB#M=yK7ss&UHi2qG*6j(RO7 z@2rp;%gudLdt_bLZjz4eq+{E*ZKGmzP_gyI>e#kzb!^*a$LQGl>OI*1Vb^t49k01+ zuDQk-w|*_E|M~I$J2;*vb{!Y79)LFC{JzdN22Y%QUFEM)h8j+az-L#8@w#{dK8`P51tmpbm_=wm?tE%iSy;# z>Hk#=&`!V%qrs`r&sFLktH*++3J zU*(0&^>a=Z-9OqA3a`JN-O}OAZPTL-sA+Bw7gC%q#`FYH`fiC z1D7;$vX--eUl^#j^bQ-RIovuxmyR`*^^f-~QR%~sb?>}t@)Isul?6=!VE5B^*u^o! zHOOMrf;b50?Az7>hDRV(t*yO%V`KBgtBd9O+Bs-uCS`&Uvd~=mggUI*tVYAsv(rpi z{RHviJ_=@T3){>->F{i5_Oo@Ua1^5$zkxHmaendlePhsoipBas1G_(ongI(DoQu?&yYX&rd*B++Uz zXf-g=q0k_=_b$)T%Vu)T?T!R4stA>G1f<(`O^lu2GN|=5=|~sfPk0=SiCx~G z8(KH^Lr;`F#peZ{vz9yAuAkz)KT0>#LLNu(C3jWq|BeriT$`>?@}EDG!Zt+Fa6b9o zgPLW;*QO$Bl`b}j6aRIaM%6Mr$!y^!k%d_vO*rcoOy&Q+gkl9>c(`VDvZ~Z!<%y)q zMaZB9lig(YNyZbpAx#+4C9^SkXyaE z@iMgMPQ%IsSP~-3l2)Xmzy$$mxc=NTXzK-fC?~N6Q8}$U2`bA{T^)hRA922+i}+c# zZv3|P?p9n?Q!|$)@kr?zStY#NrrxuNP3-Tmf9Xv0hv}hZ79PBMUvquf=IZ+irMbhh zW1@zGx?xG}xY=j!Uzr&+nISQTbW(|+YYS;i`fmXSv~JeG(}KpCbdA9${P@O0lCBQ$ zuZKlt!{;RoWg^di6=qeV%0i>NUb84$i$F!xNq7Y4Tn%0n|2KB?;E;;fZiyu;ctzDa z*ycpz>Qyfc2+EMOLF8an!m|=rvusV=l5X}4E%O=ElC+Jx_!JNOZ4QuFpJg0umCFy3 zNCu>(@}aV1>4v<+y6X>6Y8$m^8&x08-JkZ@6;Cwpy4vxHsN|f<)7>jw)gR@Qu07lu z`000?wmWOVCISWSa<9JSdZY;&n>Aeb`2jK9s4|l@g5pK2p@YGLhZZi}PLZHNa}2jm z9-DZw05pJ0!CN`K2c566-t4N=j;-Zs02LuKtLnqA5CYMhyP$lcRDu~KVj@mD;cCWK zc_NeWdIR@yIb@qjCI4uBHVukpu^?K*<$#{+o_D_o>hE#ok53hvkmlxtbf4ZwJsHLR zrqR42>=BMC*2WDnjCgF`9~tD$V(`qlWGNCdflaZ68hCWJv5fprB0g(Mm?ZKx9F$OE z+Kxb<5COI;4R~5eHAt(o$#`J5QVXC=(?LZ8eFd9ct1UG>GgA!O5EOykH0TDh1CI!G z+1cFadlUDcIU({zrG~2W+1#F*zBJk05@@=2QD~)NnMuq*G-K4$BZRhA>b>#t*FBbA z`Wv%zQ_yLJB;fvma3KxjBe{4Z)D1R|Q~LUHNJkrqe`r z1(@m=5NWFd@(1Bx2yywYz&nUgt6?6z1!uDPj+RC5!5c6cnDdG@?b!MGV_|K za!zudx2`gRtmW((x$(2-B`WprO z!_g;%emJo2htRM73BwrN7guEphNZAi%igj#A_@<2KI=pJ&ROH_>oDJN$FX^%7`UL0 z&i-j=z$D$dU4lJ&xGl8OPcr_I+KQNU4H2obGqsuXPA0!G(; zVWX1Y7R;@-hS%J`VxnD(jE<`2%T+5h#yWlF7+rwN(Cx{XUeJLOdNC}irslb(4NCcw z3>K3N$4x=>P&-I$^f>Y*L-2vq&ed{`&gDB5A1kdl8QOAifP%r_^=hPu^pI)=f5GS} zu(S&RQKwHU8P# zW(s;zu@1j`UI?K{&)_pAWIvNw;wGy`J6Nt8a$sLaLrP_0RhLiaQHcfG&aM-`OPtyI zU_u-2dj@%ig^em8wzT0_k=NOhG&9X<=-@i(A=xL>T9xOKm*GaGb;mYivfEHh*y{S6 zA7l;|FMv+pMDY2izs4~o7oD8dc&Y;P2?4yQiUlh>NBulJ>EjsoG}6TxdTydx;ec_o z6h$)C5vxb(3C8w3E5a8$` zT$s$*su-I&t^bRf`Y3|20IhpDM>3Xl@U&}Y&iRwp7Ed_lHOJ)C5ao~B*ko>JY*wW{Gri5$`*O(I>MQ4KHd1~*uJ z6R=+N*E7GBy-1^2Zm(DjUQwDhvG{^pg-yN$4?}`f4Y)Noh7m>Qv^(cL=vnO#7De`~ z&QZWp!V(LQxgrC2{4JpTlR}VdWre4=YvS&J4FSPY$H1Uu_ZnlA)v0^GEQU)u?c%)W zqp|47xEEEW=la&$!?v7FBA_)PI%ksPuVe1+9#c~bfh5mn6yTS--K5lF2jS*%8dJVJ zT`}s81WcEFBf8L}E~&KgUX`0yyQZY@ywjt)$!I+$t z438+!(lIJBHN#5EQ8Fq|T>@LCGc6cBtCy}GU+8em9BQw^dCdYQL^2slKU_?FrUD?6 z;n&>t>j=|yyck9pmcy*{87+-SIT)H1^FcC}%n59~IZsfz7)4jWYkpp1W5<+M=VZnr zHLu4%f|HpXGhg2v21bz=#zed7Kez}p2SMH|?GV%=g)BI53r^*WtilTM@- zzEs*q%L!TpiX9n`!;yi!_A;~OI8FWhhW=mS}KN7Mi#UV_J9^;FWb5zF9#Pmu+p z2_Tq4N7oRfO~KLC;Tc|8!A3xkcjcG;={RF!D!qxpZHcI4pN9N*Yb`O&`Ew!BZEa5;8)|JU~As^w%KvoeqJLpX^>TJ7N);~LLW(^dyc*Y;BX@aJ~LPsa4Z2hu>gV6+8Oq-qU61U-454I>c_`f%AB)%@DihEq_+l`<>W zLRVgJm$nRRGkc?7 z#nWyLgkN$uy|b>C4ePkgY?&Gvc;k=Pvy$V#|7cZ_$~h&8CdQxee)drRz#0#rI9t4O zt@jEXN8nmnUDMaI1Z_IMHfgQHhs6-XPI1dB#e`qv^FQl~7{{Q00L4^bCEL>GVJo|y zj`egMJXHAxD&plz&JB#nr}OiiL1dwsJmJ~#Bx+vYHxAGiF50&D*=a`nT?n7TLRG5) zcA?#$T|_hT{DZltxS=z84Qm7k^1{9+9Dg-oM^#N<$JAE*KYI;>nL<#1n$fUcWJf zhLr+yV`km39lH)*bCq_7M#*&$lwx{k^gX5A%`E@6R7&0c-7j3y+YzV{N&GGS{c`Jn zWA;r0W603^Q4r^M@R#_r9W=}J7hq@q``JY@aK3tDcm0M; zMQ!1EP-V0~^^^DyJ$+TSpigQ{3Z=g(=9!Fa?|Qk{HyVdmLbN+{32ePqn$R}3jfWC! zua?wyPBCr@4)kAw%EN%DoZ|Pi6j+ZUeExbX?yvZOWO$m9IM}->k`Tu7fZ|;k34K2Q%}W#Q+i-yw zD)7&chLoyRsMKhI00|J5umA$Mn<*mc4Vk^1BY`!dEz9}5yrP`&AOz-d{U_cnIC3+d zF#{mnH7aNl#XzcxbG+C8+kdZNlt|KQcttDx?`T|6aDa#iu60m7z;DHD=*_vjsD(*0 zassYAspl4B*y`KK!*qjC--w=Nw4h`AsBG&O-FFK~SKTxF-od~drOoxiuhY74Vn6n! z1r&jszIVTm(eHl!qWMGq-TR%q@4@f4&TlgQ_7TNhU&hBX?B~zhvS1Y7(;uS&odxy#lpd63s?qofczO%^1=-im*e=*;EjcV)~8nEW6AZSt_5SsxcKfpbI2u zOTBJ|PLIqlqiQVL8;}wavgf6C?@Q#f(lCt3HN>wDjcsa}HAOZNP-E*-T8wHgR`d+t z?}a~;gde>K>7K(@yT2CmzH7d}a({&K>L{!2JlgFVdi`6wUq|`a^ErIq{U&bR?SdzS z=xs-nBx-P~ZGLltoVauMXNQ`{866&F z7)=QJHsaIy+Y^23uUeKBhmy5{y=Y4cIudqXgEW&CVxbbi&3D^#ji|H!s@HCJTc@SF zg;5`bPL~lRoS12Y1T8kye6pP+oZ@(crcx+nBtrzpRibXmSfZM0ayTJnq*}yeB8Iek z;i$~4{)B8>q@$-C}kGDI_ULxd`kft6* zz_6*s+m_4h>x@UwU=YNP<53DwFB#>(lNVneerLRB6$M2Fl6*)rOQV6At3jYd<#IEJ zVyO>4(`Y~HziD{O6acRD(qtUPmFHlhLeBNmNfy=SCd6!?olP+=j<-wMxLT=dQQrIr zPjgjz64>hFIU~zjLxKD_Q|DXe`{bwI?L!guO;I?p>AHchvRG>zDQjUGtL!;Xgdw%< zD=Y-MiG|@ru?nIvBM*@yCq*YmZ?p`X0u#d^wIn7&U=RZDo@$uTe25i?3el+~J$%2o z`hV&<#26=9hkJ!kL;d^R;*j4iRaTl;8}8^z@3-i~u(S<%4G0K^hT3s%|6U8LK}c&moK zkmM)yu(}FVY#)CiKT5RERVVuTISDna4LQiccmMIBWjN7Otxht*w>-FbIN2_Q7P(&& zpMO$5o8o1JBSp<^+Y)zR=Dfu?yz=_J;Q0HsqeAQ#(9U-^5?fL$`+iCWW zE%3ZHzM%bec+bD+KZA}&WfKWZeqR&v#ZUojcW#+ZoKCsF}Hw>K^Xj(-=w7D^xs~SLq)ahZFSbi5hUMg z0p~z7D;nSDz(#AF;ec9a?*qcMxACf*L)Li$+Sl9t_kBg{GnHwnu4Vc-DyTatt`Ojh zBxW(T@8pnh6Mr#J=zQSAY;{m1S3|%3NtP$7?fI^?}yf+^+S=V zUw{(4^x<6NZBGvI&zsZ8IMSUeQ`+)V6^n*^@PCT@=oM6v5}P|u#YDSrF$p|a2ftyg zehp-7_XD0&FEj!ywz2Jv*Hyxm=#Q(R?)4*|V%vyw-rjpZm9K#^v1Q+PwSmmOZ^Aq2 zk3viDw&CR4b{b&y_4NT3O%cysCxU;DQuUV3|2V_--qd=SF5YNyP)gJAmPIm6)vpLx!RK7kRF*GXVxcAm3 zDOwQV^Yxzguls%WAD)6=K)qfSUyF|-xcfy7abJOW_zj5H`4 z(~ApDu}J8Di7N8^luH!6nw#Zdky1qw{a<8$pR4vmn$pMxhI*2iaE`ShxTH(RI&Ca+ z%nupa*+ZacEpV{KCMzL{W{c ztz}VG->kUAvGywp&F)x$aklytOHYfDuN<5?Wa>${S#GOKp(rW`(Z%Dy%W%Y&zx4p6?9du#kI{6B|DF@M5>M@G{b zLeDSK;VHWd(}}_U`|}rB;C_mo20QBX>I&*!AR8Z)P^T>TYaVU}t6%um*y|3D8EcZq z<&6VGVX4~#S<9SWT?C(aS%qFzh%q!!qVqm}eZGUDm7+sKp??1^(seNQbDvS#&oWM) z(Oi`$U*xWT6BJxCZaFq(6mDZp3)6Od%af(ZVP<68&T*S5k#0zqi+@ z4v&fkTOJq@mmCqJX2HeOeJ3gxBvue`RHCV%pb(%IIUO7fT>YJUB3;u`08#)x$vJM9RZb-2QFvNep%tdE;78pL4OdjU8&>0ne{^ z))DbuVxNr4%j^Etm!$mVX<}-=v`H>NK)4fURwOJch)yF1Ee1{(g11jCdn*D)^ZW!6 zuq>9kz@YDe578JCZaemLZh|HwxVoy&Kz`#pHO*vfHOU4`8OvbjlW_i(8;BIM61Mqq z>+9VQPDjhP*t04q#l7b$H#`XsycI2r*ay>-;kQZQrU|FQA?#LJq0Z8x zj4Gv1T3cR?YWuf?B8(0T)wWt?-f$y_&1Wpp2{-@3#IC0{IAtnN_*NX2eb%jdaHfRY z;=ROFm~gtpixf@*TMZU{jdL*1+MR9LUDdIe*DhJ`?rXhqDkbn-U6{zD(?*~C73mId zq^#q*vE#S>Se5rOxVyV_3CF_gLga9{9a0tUAu^U~7%z+3vSjL(8B{%GY06?&3G++S z0L{j`m^1nBES=U3hjSBYoNYszAy39ggd!^}Sc)9f=jZ3?wYEB^g=pNX^L%KF{hHEl z(r~jpxiF56O^J}MMzH;7wBhOUT*d8;caxsq1-CYe(esm04zSv^*qKN>`OVRF*AF$0 zq!3dSwU1f^v&9zE-3v?WI-RB=&6G6&6|Jy*S!)Ydz7{b|(}0a{T6GB`C1CbJCavj^ z&42=)bO~AH#1aJ=xvc==S0c) z^?E&Qw-%<7VObr@``c>o*|zuQ)vA%->k;|)$(PSJ-C8r2>jmlzv%+7IYpO1{Yb@i0 z31z(=G_{Dm_iDy68xA~H@Cek0)JZ^dd{%DTbXHUHzY1|l&PD?wvj|fbo6JGmpsTB^ z;k7l~%4NDBlD@4i2oOq$AuQZ&Uzl~$skP*e`PivU-XWwzCYj*2BEjCuN&`c>kQiq= zzK2`xFSv%&a}%0-?R)Lh>wUS_z`X5!@$O^Rt+O}0;&r*+i7*@p-sSm3;O?*+dVxaF zcRPZ!{t~WQTo{=2QO0J)$5U-gwJB_R{SSkxoq{S{B@(nZ} zTPH%?j(=mgzp@mwxI&5F=E8xyUr%klEzQkK7hXgYC2a7+V4-3G%Pd3e%snBmT7*A3 z!&!N`BSfVBeC?qnNBydI9QZ|=+LZ#N3kl{H}$1Z(l52Xgu=kN!qDM=vew zTda^DdWBlHzL2(J_8Lf7Q2C>A32HUTK{SNfSQz5}ZiMp$yzYF7zh6eLeCV;GxD?~n zfYn-(RL5vCXnU83h%~U!(39zzxkEF7Ci*^mBt-nr>eaO%AH?&fxvV|Rz!UOf0{JMH z(I8D3dxRgj>hh2R!n%P!XmlHy1v6Dyh{VpGLUjO1e6GV3kf3C=3vtuY zj1YhjqJvA#X}Mx&e=oPT?Xf!z(#QF|2BQeQfV%c8yVVYVEvB@qT7l-XUPP9R~XPzzS)^S^%J;NVys*Rjm+kYQ%;L21W!eD|jm)y;eQ#v1Ai<>BFMrOPVjPUE}avIVJaD zWF7u>m)5)Wz75K{5=0UHxLLLDc|9(C2Twl^>U7!A*UYKce(sm21rsH~O?FA4kvg_e zNke1W?I3hvzc(&{sNLwr5AF9OSnt5^Y_%U;S`ZjHp<)%{MiHhd>|Gi9{#r5cye-Mw zFTpVcyN8A5di+4i1d@5xW8`uF-GK!8^>ys95PFcDcrlRg3{@(McX$#L8I+Jbxc8=a zg1>HjBGV0Z0#N&U3P>doqG)gg2zESBMIk>99}qlEfCNR8^5rWwRyEaPLHm0d;_0=~ z!AYoOiE@}yy+X8b=}L?Wc>TO_nhJ~(lr>FRtN1Nqb35kVmOH_;hy@uAJ=aC^Rv@yP zkki=oto*@VanH)dJ93oP!+Uo2y#DknS1A#5TYb z#C7+x;Whtm`}O(XQU9Bxi@M$~#eXS_i;GFd`WaPhNatk zaIzR+P`iUu3uKYv{Bx`716CzL5uuVx;=_Mwp0G7L`GJA;uvIOU_Ngo{J!SW1CeNAa zp-&+)owo`xsIb z;|Eco2pdX1QJ)@m9hY_NyqCNFA0%PrE@Hu?@ld?kI{}my0HL@Zm&x_cHYmMvlD>m? zXn7wc=wPIbKo?+fK&BS=KW<`4IFa}1cAUW77!D}##REmGE|OLL%;5LA7}@u5si+!y zxCYgwlzNJ#ssu?n1G7nOM|A!0J`CjpWT--JSQdJ*-tf7|2zQtqmRJ^3$ztHcgh^86 zADE7$7gMdl!IYcxCoT8Ti3-R`qiMBof$`Hs9xe+iRevlx#<=MysiR zk|5Ha5|N4K=+vqbgR4bJl^YbN`@HpWGl=rNf7Q0D8hyK;=(k^4Z`}g85nyIV?^Uyq zIkza(6IC9nb=&OzW@DI|DcC44z@@<~nYSW=6>wxqfyDh$T#U^oe~o=BfRgQU(RG_x zu%@~=Cf;#xLBJ~b)|z|&r*~HoU*O_cJ{q99pgCBw7*NA&3v3KK=nMRTOGKpAg-K?s z;uwy%aJmf5>)Lr50o7abLjHW6&Epib1q!R}yzad2+4Xr^w{(!lc9Yx$W9fqYt5CYe zo~X_&U0v*h5rLgB4H^AJGVi zU$-hP!dnGLE^CF{k751#6x+peV7CIdh{j))thUb4#d#V z&~sMhoOsFL(XVi9iEv=}nc|(Q1IN-J7V~nz}bYDd(W&?menEf$9o@Rrr+2%R}y;8I;IImOn?0<46wCXTy05|oUoM56TYArA-7KS$_Bc?8D z)LCW-t|LtXiUD)OO<4dzpXFgy7wca?o9^#H-l77BdxB;}Ghr8NaPw(PLj6h!0)!1s=XnSfvX|gwkR%)#$RZZS!m@vsn4p5>+TH(c zMTmzZi^@ev61tf8RTL5LB2!TelgQgH)0~Hu zS@`tZW#;NKkBo9S3t-a%fFFpumwA42h9XE9Xt1ul|C2gc_daFawJS(pqVivy`|qVL zt{?1S2^|r&9p`k2NJ#6*R4q|gvZYIzuk9B3`&jhwv?Z{5q*6b;6@PBL6f&m?14TU4xs>XKw`P(_6BPWNV0< zRnz`PQet6Iow*kfLB~&-#*DtGFO}h<&2swp&=-ne=Z>D(K9@;>0deK{x1BqTUvtrl zV{TJ#0Ke9o{O#>6StHmLxx@Vw62f#*-{Kt=|9DOSD12ms3lZIy^7Xq=#!j@viGQV- z06#;i8pn6jzf~q53BKd5ue?q@&T~xT_n7IhE{z+42C%`#O?}iVw%~_7kF8~) zvU50rtw$Nw*-}u|O3m4EM)F|9Rfc?cBPn_5E{VJ?|5dSgTKRz6b3{-8D@u3CLfb*DDvEg!}7)-+j(2238h%4wLQIRwmu&d*WM$inF~a?-X~sZ7S++q_u_@ym7r zeYOlAVUsfPokL}|JT$)?=(fI6>h0vJc(gFnPM~N!biUeU<|H6dxV?gs8a?OotB$njYh_A zv)hi8XF6A;j)*0DF^%`pH(Ef?G+JxWdD%bl*0re9nH7$27@3SNYVw2J^^JH^ZiBXD zPsOLc6Z~_PUg>~~cG>KT3L=t=hgDGK>|$E=IFn6&u_T8$NrpK!+Q>y=KRPFD<9Ch) zkp+_fh;Wkokol&LZNx{bAZ&W`v|W!mVX@L1A#=C_6>Wo9s>NcJ(-;XXs&zP05ZE#R zX*d^58x)Wm79I`~liIzV`59W<$Fz5E4bx z7LE3fipq9+cSnV19ZdK^`QfJ%YcI0RS7=s%EB@DauG?Nm-buJE3(r+5m&n=Rqz$$Z zBR8Ic;v~WT$FGBAN+>-iSe2WP{vQ=R4wviZy@dtZ(hmgqaxLu!FVNe@YtRJrSejT{ z(}It-e}+Do$d?hp`@(}j!G7NFQ|+D)%WpSvms6!lt_pU)84(ehGuX$PHYwX~IlcWB z*|)NNvCi;Vba4(gSH#`pkr7@q%Q4f_;e-x#S3MhTvuth;!#{^RG`b&m)k_Rj^Ac<+ zF&%nUttcq{b}oxM*>NM@-c~P z6{f#$L$_!QIJEwQ0Tg7OfFWqpj;=tV;jCn=phGHPXl`Y5_2eo@kTr}zQns25!nRDc z4(%>BBrI?^NmCH4FqE-!C|UaI9Mg4j968r4_tvtTV~OcT(XW!5mY_&z32jvv{4*WY zO$HQATw6H>-n;}j`pD3FVg{ZcW1v8R#ZDq$j)H{$d+&Y&w2B=GBO^%!k1{x4@G3Mf z;K!CHAU60;TSvzm4o)VS!NZ+5Clnzsogg2dYU97-buKCG;tpNYjK^->;mc5W!Nuva<|L0vJubq< zmQ#piZ`6%`Uu+S_Sc~q^ogG7czZVvesYE!iB{TkNLd{=}J91&D!c?X2;ekP5_I>pJ z{@&kchh>1H%}JvAHjEZS6%(znBG0Zn;n-&AvfaJe z=&l_OC4wBV;+LvPwP+?5i^{S2;)-cFu&4^%=@HWReOz7>;P?%yX@dc8_v64+N(YAJ zAFu+%pqdqAIdPqto9nk{8nsqS=9)QToKJ_yO2%># zZK|>5$&9xVB4ljg>hiMjgC{36mRyuK zGq8YV3%X!uaXWm4p5*%c+fQ4xy?{SbL80mHQoVLLfC$Y8*(D9~sptD4utnQiPX9-V z>vrqx9An4Mf*l|pBo9FpW<2E~WIV)@8@+C(E1t^K6^o7NWU;eE3!`Xbg3XI>)ObdT{*Xpd>PT9h$V?ues)nyY9-)F!_bax zQBcbADapcq0N+`9M91+HrrJ3t?v$GNc5PXfc$sv=r3^0Yf5#^OIYVT@a2xm@3`JOS z1tHIK5_e#j4F8S~A#Lk|TP@J6+@q8_!DvrOimQT=?0+Q4jf6)dX~)uGWevIigFlM< z!xA!DO(jDx)!bR&egl`i4Uq(@0SS}adu=uVRYs1JIhZOw_GuuFqKtnfeTPLhU@||z z+@1d1dgWUtg)t4Ki~mQcfM zb0*DPZ(Wq4oZh|A(dAUJE_t|8ME5Le{~>ecrz*QPNe~4^Q*jtf3FL1~n*rcD@`!6x z-g!_pyM*$}zUf-t)knONA<4wU*DVhCkTCp*eOAn8l4Q5}L;Ur2bpdrQ0Hl%v{!&t;Z z0h^FN;XUFM6m&E9&bKqArlUG7;#nRZ{X3p6cDJa@g?9t?mbRIHVWx&9+j78=)Bs0iP*>|Ak z(sO3H0`F}yadSy1+O5GTGUC*&(c@d(3Yy4TP$8zZ5OS%I;C@m%pKw@DEb%g3ID_<; zf`WqLpg%T!l-}4N&e$tCC`%}Rj()Iw=hD)dx;tuCg=!!6tDUzgf`Dpbtt6Jro`3We z7i?V3PN%?fHGNu?Q8+zH;w`CU)r3lONrfp`8moj&6S?O4W+Ihq zi?IFrZt)OaeDmC_)r1Nmfc~4|R@ga`f>JYH$#=_t(C=(;upgXhQ-=R6HeWKd{Ea{W z=Ey0FK#aeg#1R!XH;4zEE+X`P%6PzA0J~_qAc^@g^AQh0eJLxSM@WbW85!B$8p6YeXuD5oy&&I=cp>}1P6lTh_ zvmL5x{;=V!PQR1OMYupyN)N zkA?a5=r5hMIQdCMR^($<<&&GMt|Jyitk~TCQI&*v>!1$rKccAl`b>H+6NO-q?tJ1> zSDxJ|kLa>YJj<%-6<2&*!d!RyE1K4gpzCYfaa|O4V5svmZvkvKsTqm7wZs3E!we>CwOxlEcLkS(EGBW+ zABkVUvJ|sWVlP9OQOap|ZC1prVB_>8X(Dq~D*3{%_&3B#<=PxYoRMR`~1%YcLQQl#26TCTRyH091H5pXXVRJe~_*E_yK4z zT4mx2Dtp<)g!j3IgxlDR9EMGp<3xlCEL(^!nGVhhBl7>a)s}{~+14ld^?kk8ZEkKJ z!pKmaoacR)VWTYIe$dksD1>m~IOFth3l>br4teB1&~Uv<6iu2XlLk+}ny)J7>UiwT zsow1Z?Dy0#mu~jSgVKP+4m<@{SuH0PnP(z@*Uog}9KRFC_7tK?hm=g)c?}QG$!`#! z0Aft$Q+N?(6cN6TGuz~tEJB5_AEfLw&hI5wt?aIW3{RW~I1kU_5)vym?Yvd_*2N9c zdvXOTGHPNuQV~upFvUDK=`>yrOotL^@9cK@oxm}cKz<}m20u1FZFqrBo{JU`si zo!l~D3b}qy4Yutlu)pBNgm(bNJbW==|D)DMF>fq zwMDI}sHhkxfprH>om}ePxM=U#zTFW5>grx^2!;JWSHg*Tdk+03*BeyXSXuX#6%-z4 zXJ+j4a&iR!1J#DRH5zmdAWiNq4h~MkpFh8kj($M}p1~eihcjcRVCT-)I}*E7kIIl! zBqw0%AG<=B$f!9RaOF6i*5Y9%4k(OQb7I=o-#i35!iiqFgwI&+xw1yM46a$7vxWv( zg&${EEe&}ov;8nEK}QvkphtAN=>rEv2Q?E2=pwnJN)%QMZE+U(dsjNUJ38Jps+TEs zQ&r6yri%L?v**!%--HWGwCj)T52pQH%=?;x5@(wgco!ffCT3PpRJ0?^!u9|AdVk`8 zhmYU+%fzJLNJppd^0G_w{JFc&Fw5d1>4bfF+#NGVpOOf5XC;>N3}gbYTPe;8iIEhw zu&K^pLrHFIqZIGK_Z#H9g8e?b{1SgE(4Q+ax}r$QS@5)d@;Q)XHXLf%TkY&d4tHSy>_my57Qvu1`j5Nx-K&d zixJSR9$o+?Ri4UK(7kxeNrK*sLs(l(qxrn>CYT-rd&YlEmZVw(4HFdf=jAAV0@;H9 zB&XO|e)^eeh6%y8yqqkW2`F&0U_gG>fvjU{@qFPK59%gu>ZOfYylyT<@jB<0+BAx?V)!&Rt z@U6m@Y1;W(MQZ*(0iB_f1esE1Snto*pu;gltEvD6>Jn6I4IUmI{!c$(;6wW|bg@ye z+62?zz|yTYV4v?yuz?BGk_94-v!(43^K(urz$Ll_SS6t({nYVW89Xxh zost!74Y}QBw+>HA_K+%vO}u(_*^7t&^Rq?%EaNN3{ggB3(+4H-?9AH#KVYN3t?lLB z)YKG`y1F`XMxN1@soGEN!pVC9`brsEDE4#*Ipj9qN{T?n=KgSjWnE4$pUiD4ex4%$ zT4uG2Rq}%aA?OxExu`MD-aGoaUfP(MnY9@KXBjaf^DsE4 z%ufj2g4i7U1K=`FR$0z-hReNSGS?V0W^81OWAwx!J=*M9Df`jUEQ~m%OZ~=La>@Au*?Bu-&1=n zqyIdJ-6$wITx0FRf-<^7Ffug!`po;hwER9$`@D1s_d~kueBM?D9jHbX8gHO|f&$t% z+bq1iud~O;$Iu|(m(1x>MeFEOk2&?`cAo|v1rBxnaHFUk++7H=geG}vey8@eY?qtz zK*GU65QNaOOjo&lp1WA4oHt9z*H(KOL7hutIg@Py+J+@(XJ211`#9bCHCpoVdWihlHud$! z|D2eS@v~R0;vr8M#OPj{8bAVFZ=OB?K(`F!1cBFp@HDkT9U5atM^s7S0MxKs8j^}k zfc4Uaj;=1e|IvuY_4hIN*MA3U{@?B5-v)A)xn8-Tv$Q@VBjavq>0u`{H1vXM7Su2< zRj8-60T?}#D-4(kxb{TBJ)(pg@Pwr}N3o zw)6W_j`M7;@12Lx+pW>8aL$&Y$5Yhx2PGVYZ1lg3H()o>F2W?SrM>^xW8JsSOgo6q zgvIZ1i3-Y)M)$YkugLjFGTk&_ppUGil0>bT HanSz(FO?~P literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/MeDucer_thumbnail.png b/resources/profiles/Geeetech/MeDucer_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..306ff12beefed4f121ec6d13386557bee7a1f2bb GIT binary patch literal 59169 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 ooA+BD#&LN7SNi|y8IehQ1iX)M?O)J>Hq)$ literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/MizarM_thumbnail.png b/resources/profiles/Geeetech/MizarM_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..b0bce4653eb754cf83e25245d733d360aeeca51d GIT binary patch literal 48858 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 Rfbl$(ytIl`t%OPF{{V6xGqL~x literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/MizarPro_thumbnail.png b/resources/profiles/Geeetech/MizarPro_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..96099c88f4c191d23b2784f3b1bc1e376b2d86f3 GIT binary patch literal 35007 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�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 LiZrP~c*Xw<_mRR$ literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/MizarS_thumbnail.png b/resources/profiles/Geeetech/MizarS_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..9c0d3888578fef06df99e880c7b96255f7c4a8b6 GIT binary patch literal 35146 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 literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/Mizar_thumbnail.png b/resources/profiles/Geeetech/Mizar_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..46481ee07fb9a7327b2ccad381ee8889ea00f1fd GIT binary patch literal 27120 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 literal 0 HcmV?d00001 diff --git a/resources/profiles/Geeetech/Thunder_thumbnail.png b/resources/profiles/Geeetech/Thunder_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..73b5b9bbd418b7b5ef56a54cd9b63e0458ddd57e GIT binary patch literal 45095 zcmb??<8vj>^L1=)u;IqGZ*2R<*2cDNJG-%M+qO2gof{j!&-caiA3QZRHBOiL$SuC&l^6Rd8isX?azMB)N>rAZKom}XpkEseHAOs8mU z>iOo{Aq;UY+y4{f`aPJNmf_ysq%T>WBj|aEPG#WoeK7m__VKEJ^ZNPuRrT@MxEuU_ zfZF4a^_umPC9q?&vz^e>^L_RB_-@Yl@KX@(sFbS+)EepE<(O%(6EE;(Deeh%@Bgvr z|KSh1e$JU)oYsXG{p9<1f_=SV>an*EJnOE$n}6xOarGt&j=wH#P568|{z-%_5kc~b z@3hJ|%Y3ZCbylXw;k*%gL^%y|q1RV=4T46e|;QldP-`&5EQOoEZNp zPG;j}P^9Y0lozM!OQhG7WLTFsw^Zb0vK!hJFD+}^7f$DRT^Fxxdw~jP(IpEgCd&$A z1xEfRd(T{&rFVJXMR9BBS{|vX>)AeXEVECHHegjQS8dd_A1LsG8ZPWQLG>r_;Xo&< zT&Hu((p<;m;$^#z*EAjb&d)gBUULSY=BrtvZ{g(ujphBx6#bPR^H@+z31YV_)SjI3 z%$Vj>U<{XOKv3L7I*8LL*PpqRr3|lKDlkmeOKWV^6gr3W1b}N4B(`}oe{!49p zAM|^M#`QaNO5A-x(epjJ%9bR*JI1#|iRCf!`hbJY?Tc*Hz~IAQ@OwMdtLrg~T=US; z_5t&4lWMtt;<2f|^DinfiuPNA+b-?~mLa{)(1?`rX6!#S0^&^a5bI2-^$sJhhP3O9 zCVNLqhipgBc19(-y*7&3wknWo($zIcy9xZe&2$R$x<=OmYz}s_tuRYSLAS#k#P3aP zC8|*lqHWh*5YitTeuQQ2b?+|*xpmK4{-N8t`{K9CocXi;7|*G=7d{#weeF8jC%|DH zD?)fSA}XJ@W)G>m!GPK8M~k544myg8+7Ec?(84;}!i@kC^1VvuyH+06B+789dp?mz znWU!Fruq%aX@@bu+EMAToOmyLx1?9pH1aXXl4~L>YDPL;bHH@l4rkvV&)esTZLC)7 zpJW?L(<7W1VeH}x37AROXk@qHlgOg`Pen?732P|`_t;nMQA@X zSSkfsK}ixO3q49&f;OKa=RM>%1?4U&nxW!fD?Ia`nNXD24kROfo*q{1Bb>00@*mX-`YUIpe+ETSmPl(+y2wYU>Nmyu;Y!sD zWamj>@bhI|G|BkcsXcWlW?+={r7)(r$1EP;;KS6=)cy1*gh<$}2oS~5#S`j_4R*P!jTFx&dpr12GBm#ja z2SB z^z|8Ve}Ks+WJ%&ZfIlYAAyO*68h&9yH4(NXjV<13*r7w=j@k4r1k^XOwkfxN?yaMQ z1}GADlea@vq`?$UNfkCr8Jk6W!m^;q+Vcvhi!>6QMYLwx3o#Im<6-OF!n;+{WW%5I zKh0^1@CBzbyMdnyFl?$$%c5>XBoQSOR-Q%hkJb7flZNk{; ze+TDohsYYEybp{zE6h%nAwh-iu-IbATHBu&)c9(N_ocd1z7tu@T! ziy};rEC0SJ;lLgK8A7aPMDXAxQtihIo#@>{<%FHbEGywC88{r-!3sc8fNZU#rTCo69oR%L}=|Fd(xCDTSl4lY)HOBLq$}mR=APjLZ3Wk@bGF zoKIoKVp*NbvNd^l0*i^B^D_tS%BCPciL;daLTki1HE}NT&`CqJJ-5|~qr_^cJ@+Lk z6G%ahy0x&{md$k&fx87#_n*oN!@LA0i%O#RLQi=!-yJ%}+zVYO-=T~!f5WC*{ zfm3s1rvgLGP>o&SeC)i}rwh2Xk|nyruoOm?U2jvsI8E;jSS--ED_$xdu?^W=NSUrS zvwD(TU2)tI%0&sS@^84PkUMS%BJ~j6B>a>u%PK8T35vc>Df55snzu>fIuCG4m0wW! zL`J5WHv0Zp7ogiWs%qkh1F(WUfd+hqJ)@iJWdW981#G6 zftM_N3ct&86Dm|aD16Cdg)|W816Qn*8nwo?={3t}S=^l#N!`SkQ-TW;$;6Ke_(5u{c)RH~40-8V+KR_WL!>*c$MoIj5cl7YMY z(A+ifLIs$WkPvbfqxX$jv0{C-CN+p-0}}y3IL^$2uO_8j*wE6YX5t}rX1K?gW@{)$ z{C%)lxwcWAIY54WY7f%zj)L0{VcLB}?K+@+TsH%W5XCb3iGuf_*-w2$iH=4KJU=m^ zJVWEae{5BbjK+W&*$%~E`=xtTs}gIDG2G;Ya0$VFQfH&mL+>-KuZZ-0)gX&G=0lbxVa+HnEwc9Szna)(=*rn_wx9C53m$CZvf>uw_YN{1^cgFktG(OwHnU(6gEDSr46X3M7M{m~^eriebLbtbJN z5m-+9AeV|3>I3^xXo&U4aM%H7!hg^a6XqiZ`@HQ>6-D;1deXEzEyU64>q3UW{E``& zKyp9_PZbxW^j+jEejc!q+QP7yw4x$9%PE+!Scdwf3Z1=1a}b-KFmaer_yvOtDs}6{ zhC4t{CAos>ime!|Dnc+qoUjy&{}&QMln6|ek0?={RN(`b$c+OSdJ!x~4znNl#ztW5 zlx?|o0`6f6ETi`K*j_@BD9vhxrJE@wG0@!@lfBawjp)c(d;i+`*Sfl5033{kb==pL&e= zGDlndyV;E8hvgKJCO7(JVyW|O$e33d$xHcDl;DV6l)@tn<;#@$qF!oKq$Py8d{f9L@X+LkJa@O6!B$UG znjJLAmx(0+ZX`g1gp_@T@j_6;&jc=AN(u@J*1jL=tc=X{h__G}{3suNy8(s&*cQmu zOSkP@=b;?5Vgz6V;RNogY}XCjoxEh(!DzAN(3$)Hv>YYEIN`FHbL7Qq1}fJUaT%Ra zQyn6nhag#f9l~P@1!j$ct<_Xk>WlV1$Q)!cg=?C15k>1DKRzGVhVER4L!7i?W!Y_N7q~ z8g9202m2Qu*%!k5Byymw`L3-1js8MlFI@EVX|0E+vyhLvh=)cAlrc_yIjV^# zQTps~sOzL&7RWErgFM2`-W7 z0ql4#WsDRAO`dRkq8%2aTvr`GctW*>8O5fDikg+xviG#kzygPO6lRlzW~L% zRqLJ2CcG9}qapG_dCEfn!MLVX-uA(Om|#5za_ zR!LT&ypzjefjQi+L4&FdJvIO>E(3A^0R|%+(ozMeD#(O-WXoE&y35=lMphtUi1^Fv zDS~+m%Uq%n5))6~+HaA?nY_1KODc)&1Q$$x+I1cdg}vyLy(F&&bPt+=CV;?Kd7_^`li za@{80+qD-Sc~lMvo!sBC7by(MuwIDYNREah+#x>!S1x1w=ZD2A@KkTkIpk9*Tau&0tiz=b?Q_UxE$P3NXqMcQj`U4uQ_!UZu4!TyPul7ws2wu<+<sF%(QySBn6)8D>*?Yt{YnZ~!M#iMNOPQzU^(np`sTJ2eOTqW ziKVN6)~K}{XbFW4axo7xbWpxqcFG=BiZxwbpmMXf@^krLfj5j7<~9U@0SR_se>F9( zF6{OWQyx_JypzjfiCZh$5s|yh9Qv-YAax-Dvb%>6=DeXeods|a!RZ$=IOWu~ao(G; z6Hk-q+*oJ8UsFpBWqfd{V+2IaWnyvsE=jq+pwoB;nTlNOk(9H(c+t6Jr6F{y1OS23 zmLZ*f*mOCb0+Xxgh+QH;5ie*|;m2CVyx<40xp!ep(fPU`zhj1q#F|rcX5q3O?<*C< z3Y9;A5^u9hfyp;B9ASKOP+W2_KN77?`*>BFb&)jn~umx~*J6d|8u-$N^Klfx((#^soowQ=o-uZGD| zLH(8lFGxUEESN!#h}zk>UoN@)B}Mi^mrpgj;3=zfbfreX1jI`*;g;`+n%ro&8w;%| zS&jvV5}?J0! z^A+ES=vZU$`?&Ync>%~ULz zBb4hL6wRBA+I<`S99jnutX%wvgktV>L5o5=X)vnFX_W8e8@7ZBXuRiLIJajRJ#W<b5#h|nc0`;nEDbA^owq7uC9pf&{kvYR@BJa1e1xt1NlTt6eX2tmbeTA~|pf;x2f?eU=XH zk&DC=x_;R!bY7yX^;an2%pDuuUN&c_Rp7XBlJbgwC5kqB>#c=vCNBuNJCXcRupK z4^448J`o68m0IR(l(~2I?($U1k&>fgGQd#k1VWgXkeu~?F)!6&8S{|^GdooVUuu4= zY|M_X)6wYh(3Yp_y2q&Tsp*i^T+LO3`ysHjua6n|5qwIs(Cs%@S&q#D=_!@ax>$>; ztF5pQ<{NTwdhX{MZT}*rTq2FT7@_=vYlHL!;X2umF-59RnA>~;im(L5?sLB2W*lDM zi_o43h1kP`eD_58e58XbQET;+F?n~&qjGN05f5n3g@NQ#eg7cBb@WaGQV{!wXL>JRhu4~-8 zBID}w*D$pH%@u*?Cg;RV+-F3&zz(N5NUtlO=fdmymFmzT_3<7Zx*q>I{sR9=Ds4fvbYBuqwkR=wn5sKR4AN5XTOHMqRj#Hg5z)L0~B!I@Ap_&ezLE?R&u z`|FwLXw+vS)DRpI`?%*}02&LSQW&&RZygN*+d%M5#b=kwW7|psI^%Hf<}X{^k(lLa z_HJ}kUZ}Q$pDa^jDHSHhRA+Fv8K)SVcO}G#S+Sq^`?`eECHZkygzD0gKk$>Lxfcyo zSP5pNnW@zigXp<|mPRFe4KroCA4g_Ml=)Z);3jfxlSL*H5s+|JV8Oc`PrQdVJLM=@ zhcOujyA_U-H`um2nlnr7;1J;OJ;~QR=;e*RYKth+RLDh-7ox&chPH{+*|MZ5TaBb5 zVV?0Js--<;WU5GbF(InURLDe2KeSkX92IBRMkmhSp(hkOMF&nNt&{!}<;7~!>FXe8 z<R&Bnr&ThQFDopvZ)rm8u-N}g*T#eWsB5f z@J=HY!-}{sZ5A%@|JL*tX99)p324<;w~I*j!z$i!B*SSMP+)h%Oe-HN-QTdX3&~X0 z1%sy~!igV4^HarRaV%|#CR~V@T)}dvy9^xjjeA?po>Es)Gpy2$!<>U{-Cf|m!X>4^ zY#|q3KfT&1Qi)@r8)l6=DHt9B`Oa zliD^^oluVPGl&vdIx4zwSKHynr2c$&zp660k{He}0Kmgd(;*f4EsMZl%m=t0?evcC zbPrIXV_CAv1XG=6{V^Z$ccv4@ zHiH(W$e~1`sgQUTSvL*6$2Me}zO7Y0S)M(9TbrHL-7klBNF=_qBogkV+>(SzaFF?fJZ|1M_Nl(J zxAo=01Gtp3#w1r?KM8YM>7{GDyL-#i6DVE6U(l?^si0(aZ}`792^eEpNineR|Bbxv z(&Yb6;2os2oWZ~lG5$Bf!7{RNz`%&Xq{W0)J=QO~-T#_Ox?X=)R%9!j0w_uT%a-d`YsgDd-1hBn|=tPfGv?Z(yaizO(S^ zFfVb=U8K5HQrjW&&fO~2DMWvoB1X)8N z->PSv(hH9&glbts=QS;h;2%gBmGR9w^Up#?1azPcxPWcdCxf$tQwyonVlCNlegfi5 z2}Yr-n@gLYlF4brl@G}s7k*0Q{~UGHAQ;tq^x~IF`b{2pK#Vl_#f*x8ATdX&l+cvL_UHy9mcSs)oKcxxm;`F@_P&kY|SNAeRneMhYgEMp&|HMiZYmtX8L+nVND@ zt6TzNif>6LRn;%MQAsZpHebUJI>;xHD^#nKA&F|$uB4}@lSGj=E#sJ=!J*|fQz{r& zwVa9-R*z^$vy?n?vy2$V3L``w0NUb$RS{^&Wu%KzsEg}_%5mz<2C+YSjNG>TiS&-_ zIPJF-6g2|(`oU)eO#W+W>A7*N<(YqU=0ST?43r07z#;qj^QT(ln#(?b5yxbcI?lHm zgDK8fFz#TR83}RPtTBOHx?aEbPsX$vOWZ*Xb(DIzk)|Cx9={`jy9RA)&hYRsa;!vm zC$QXU7)t|9JW(zQ$^^-1l|0HghQ*?KULtu&`t5tIml^3li(~R1`ADFEGJLb5GU?w{ zMMI8+MXG=}(R`&oS6zZ~w3=wJq68_5L>X}6;wfPy2ofQ<#4ma%8ppable*O@746I~ z$~Y6gox;*m{8F4by&En54!m+G3`xrN+q7Iqi+!o*@ivJWreqE4PuZlQ6>VN+oDRpN zwrPn|CROYX?4Omw#oEY80LCFlAl%@wVbahrb5utGGi|8RYIQ85b+tEM?8rJG&U=7a zmr$~P#fH=4h|Yi}(`f8tli)tpGh-S?8^1`YJbW>OTv{qA1Q6F~yK=Zas~Ow^lUcND z?a537Eki>vDh?NT006`VqgC(la#QQ{xe&naJl~HN)si{i@LSN$pT3+w(ED|TRbZ9u%@8AC!4!iR$u+#Bo z#ob|sEF+VW>_w9gMSHJKx?$$KQ>aNzTnu4^USxCp8Efho(c)P%p~Q(~Oo{^>m} z+`c!kC;>OL?$xVFKoUVW(d)!5!F-Z@!wsqs`KX5U-nnteQN;h7wg8~e-QEmGFOj+Z zeH-vgk8R@3^#b=7uC#9un&$lV(HNiOMG%5EY903uMg&q8L|+SExotiTbN~ytEG9!; zD@2h?{InfXc8}B3Ll#7n?IVL>6%^j+%X=`j=u^gIfNPBZ)jtyoy+qc>l7=e|TR#&s zu3WV8pTjk)xI!|47aiQi7N6bCI$%S#Tn>0H5^&|3opz8Dj*%wFLIuc6UdgXA#iHC& ztreJU>H&3Y*lFBqvghFpI6`olg0n52V%93mt#)C{gCSV2oYvyk-V5&#kTS$0=52EYv{Bh%|wxwpMPc6f**^rm=CoawMl>0D}X=>l9^gxXqg+126* zUD&7EI}*RSGJyz^G${wW?RFy@Z0o`5N@TuHrg&S_U^Z+%PV(^M(L!{vv z4!LQK^vca=rpy+*oknI}H5%-wC7_0)vrC=1-{YLnhv2Wd31u3o>hY}FG0Wf-hS|-a zS`Vdy1=2KF))BBYa%s=zX2a%wyw1bs&^|*}2i%zDQ?Zk>*n`XGw#j?G zE5OXJQOB4Az`NecyhsH6?Bfr?8!GHIA+2{hG_?0^cB) zSM9HdDrARtbxGfJfis03k|pDkMKC9P&4o!!v3}+5J9Lp#86!QK1p0)dL&}6ORmc!I z4UXQdq)g-m0FV0PjlVyPe*3=LL5%)O~R;LU&t1!RSNTNYu^474$V_~hRsT~2Lm)A3Z6?+|aWH+C6sTrp|I3)yYj-Hc6wQFNHKa>^6wU$RDvl4Sl&P=|q z+n@4TEoO(|j#-!W%RgSe@`2^QqlOoXoCvx-Cy&>@dIZQqs@iHybXTgSX<`om@`227 z`+cY}7ai-5{5rJQv4y&o1eRlk%df_<2KnW6m1|+5$DitO zm|BU36ycL8uyBYY8T3Et=d>$PNEOj$(ENciUYb>$qyV?G-vXE-pW!OD1@y}1FF<-DS)mR8PJQpy#F!zDiYb@J@I zn~>mJimOr4Prar}kah>^+PD+JjwqcZZn6xHEhB=JB|8*@V-gF`5|30QOUdG@!w;~n zyAeUfEGj8esH}a)a)YqExq8a+1(z#BJBnu&#q7UOA>s&u3OvGl@Sqs_KLx+oFcyHD zrt#Js9RFFSi^5P;ZzkOuttEqVw7qWZS`v&AL@v!k@CGH{`iNaqL~@m9uLo)s3`t?zCzYOnDYcxPZVP3*OT zVlUgA7eJuVTORvj2s90kR@_0xiMK)$Ik!VB3$6yIY|3Dfuu&x}2#NB+wG>G^hCMr(6i7 zMRVVYaKdpxXe;O5{^;|MJl!;L_LGx#(YY!@JduU$nf7Jyl3TUW9s{};-9|o#^n&t6 zHgmW>i{0O+dYDNJ63a_toqJf`|Ipw}S*&Z_z|vt$u>SXm+p(_Ue=bJ;tf&0qjKi#Fh3bC*h>4(W3ls->E;bM?05X@HnH(QlO=GEW?YugwK)fL#AQIN<{i72iXOCf+agzbn> z7S=99;n!P{g9YM16EcUnCCuoL2pz`I7*WKKOF0EE0P0oX6v`Raq=@Z&fej}w0c)n^ zCeonFbv}OVNQG5(3wM;s_n#$Eoi)ztUWNlldX((k#Z~EzPrhF~viJzUIocH() zGk?s)6ln73QbT(y)GHSo*&4k^s8G02iMTW5W@r2w=51;|kHDKeEiziGj5}Rs?As|8pZgNs zuLV}7=%daLQ~?18Y4Sir=c`lQ%G2|mm0CKEK!Vpd-Dj_9Z2*H5ru?u8h}v1O zVE6YXsp{%zXdBBPlxzmQ3(}>^>@a%F^g?tFGoc+iCRJ_q+CP8k@q$z`TWl5|&j+sC z)5|x4M9zMdZ+uM{Y;nzIB&nU|B2X77zmnftHEfG zz_MSs@~s@z|J0knuQRUOty`YKF`(L&LJ=shElsbQe z8L=2(=DQ{obY<6JDjQH_Ur82mCzU- z{(+f8z3j0+#rS?{uPHAt|ElbDb*+19a$UXbvhVzmdTg2c&C|p({}!T{)P3D?v3-|H zSL-u!?uy_093q?RHqFN9w@GN5<@fg6wn7BX+u>5lc58j{3;BgB(@vDa5P!KQE_o=v zplk>4!rCOfdEUZy8K+Pd+q-^P0GTXhyuyp2U8lG~sBxYgE^71P;DX!h6s-0;n9FG# zL-u2`*DuHYV_e5$#uW7?=}*^RJGnh4qO)Erxm{;FUUKfd+&E%fyc*MpEL3QcuH~JuF-YrUF$V{kxLh10TJDI^_?CAy=%rL!o^(Y_1l74 z`bU1sxz`9=j{bJ9JqQHV^9-P2=zaX|j(K;#+5>%Eo9Ny)tN`g@A6%fJdcsq7d1!0j z7}{em!@!I5wj(G)grtNU^$WGDm9A;WE=P3#?16;5*Y7el^d7@ET5MDK`MZZ4gPaJW zhDrYjyhb9Spg1f}b2Yl}1P=ZeQZs4NeP6E^=6gh#&E#V-6zYrt`kqr-B>+-J@-)gExek4u4=#kYZ1C4xoXj|zxpzm z_5Z559h3~4ZJ#ZfYu+o>ivHi;UsktdMDIhg-@A{s?RSFC z7-qOh%2a&2+WD)$9{Tb9!)(VCdCPEZFfLo}X3dvDM|= zY~erIN=f3-B{ffpaDIOWeiE!VUf9>Rzg5Vu>^P`6{@#+%f4E>`TV4k#5D|WF_T6N3 z{+H3+?X;hjWYS zhD*47h5kX!ka}Xv*7(w?>WGW$(k(ZnnYQLg(mxh4;Oy2lG`#s;EzhjfUO-aA~pj)!IIZEh*u&pV=MFEKTGqkDq~m;Y&U&bFua1~+W)dsJH< zQcIw%QSVs;U!J-vkDW98otNYI?XRa+y@!FHJ-Zs)k2UTFz0N0}wQsS1x-V5=pFt*D zVaOJkfA~S6n>U3-z*>zZMbO4`@tV~^b>F+<@%py=j&J9?S0{W>2uRDx7dObX_8}0#TYup_Z;uT8>kJ{O5p*+oAkSmT(&)!vb_SLTH=V_{xCu{E2^5AM(Sx%ukav_@4S6NSo&oHLnoeW;`!{$qm_pYyEW>eub}dEwuCn+?)40I++e1U4wz zYj7E1&Rekm)hXM(ULU+*)EmXJCW18=%pvl5&KNat8mAZ^yFt6ZzyFVM_Z=%;QT*Od zr^xu6b4yFp46WM*1QcgySD$YiJ6~>1EKoU;iUxu;7i?^vA)S6+h`b7dgj{fC(*yEvctJ~8p=31AS2e|8Ufvj zqha58yED$lBp4rQ7D)8* zu!BpTRtGO72}IHL>gb?OL%@s{C!knsFui{uL$I)py$^a4K(uOchklDwjQx>LKHy&_j! zQcP^@EWdGpfUa~_?}wkq)*h{59K%bT_=M_Z`ENY%R>~_`nuH%kF4QT|&mX70K4*GF zeez-4psePxq7enbKEw&Qqk^JhVk~{>JXZ_@ORovWNbHv$(Tl!3wO~;TMDM4oL1drv zN1oK-8{3tS_s7C!uSR#!r~6_|2LG_JrBX?5@dl{`y$E;B1_Sg3s1s!8I({%KZ!dCG z3@=Q>JOVsFm*5sK>9jNHQQzy~?H&EMhg#tf#pf z=j~qad4Ym`Y(@=WywBWmdQ4-`>Ge9V ztR2v_wqNC2cfPHG4EG#iV?5sJxpjTYRX^tFb;Q-se|5Ebgn^`A$z_5c(uQ3^WQJFm z6R!qRMV-JEhP>Ve+t>}^^k#la(q8h`W!4DY9=m_=^fo+Y``q)c;8jCM&L7lVT+(@5 zgO56n=&tZLRP;Wd4*xWGNJjO$ArW{l*Ux(XEc+VVpz^rOu#^5xFQfGzC7-Y+l&Pt* zYwR(Cfz|Bs1EAC?y-%)>PonP7LOdAtT9Z#HCL`ZOu~JDTxMHQa+}L*+EO(#`8Y};z z4nEp{+ABaBt`KhLIYES#pLg`~63IO05x`lcH~6v&jxfyHkt#b~5mU`gw1A8@A>FEx zh>e(%L|xpcodh6X#!DvucM+ZS-8NcpcSY^o$VQNzaqy-0&P>^lBU`9Hnh_G%Pole` zh=@L-R87y!&o5q&qr~_pJttk<>|m+@(C%+@xqH_8mvAYHTeHzGP-qYTRl7=s zk_JU)I_dC-oE6Qg|Ih}RP$QC*s8zS<-$CH`1nKgAm=e!txra_GDQHJl!<{J30BUcS zM7`)ink|1h!JRZ2n7Ld?up-KBw+sXI>D&E(0NFq$zbI+x=_)fcJc1Aw&kItJN`+K1 z7p*5rOcKZ02~H+I07s|OG)a<}dSVIVFt3PJDpiggohFJRYPAN{Y6ahQa6O-%?rwyX zEX>c*sMj#Y;`u&~qi|gZ&+|EQNp63$y zMZ6$b>$;9Fr9{d!%>`nUwfIsA0zaUur-yQ>xV^ip$19e~1b!NDd7g*sxTF)^IAOJ~3K~%b}BwiQTGytq7 z30iBS+6<;vMY#b+CnR&@=+#f=&|P~OIp_I2?+Gu!?S><}E!D)Q){J@Ph38V*@oavy z-^#)80X6cZ)h44d=D!`FeMd4~Hw>2q7p--`!eSWnwXqp=ILqNZKIM^B^j$DaR5PhM z&RSGc(RJqOsMFTM&fSDjLSo3$aT#H2pEhdcF*+vN#QiPUo2B_3N;!GaMG6RfpTkEE zQ>j!KS-plvy+)-nPft%Teh^TvRnnaRh@u!NQ_w4=h~pToHN|29tu?;y;rl*9fFA_- zet^+2S|=EjzGt)9KsgTRgnGS3p-?~wLA6@t@Zpq4`o7rIh(BW@FK}v-&4sk4L))uj@;;c9S4I}5BLG?%-U8~`i`Y_>9q!SSgoQ{dXHVx}9 zJe!w)`7VmC;D9QzZGfNk^{wZdld!nkn9ts834HU_r>wEB8VQ`re+xiM(v#x5eTY(4 zfJP!zK%*&Gb5@a_(IKMRk{&}yL9-0%=6fjb-;c2luIJ%7602p_h`BVYXKAdf%mHj$ z-a5U+v_|eOslZa&ptG}Agb+w23B!=-nHlEhX0aB+ut}pCvT9(6sUwG}HyTJOsnu$9 zb#)O%QGUZHrC76O4UI~u)l1pxaTIu-hm-+QHYgU0L{Y@V#016|TsOVp z9M{8IgX1WaatQ(-x2+o4>TYj+xAvb!M!%G_SfP+I{n?TUw}i|EL@iSYgp|~gNLQhR zL&CMFE`=~+%i}NN;y1n!m924{KwJeKgL2b&F^Nd4x&pj% zf4XZ|;6N4jQ~_a`uL-&TZcD|=7hQXrd7ia;vk>agBM)e4i4u$N3WmBR#=zXXBvBs9 z0Y^xbZc=8_-NR1W~%NRg^;O*TO0*i+*T+0?bP^ldaj5MZsP*=***p=|JW z_Os0;j#_KFyStg5p23&|*L88-v|6Q;5YiC{6pBS$*CPl5j4=d3fyKotNs^?T`WU5O zFlZekghkqv=a)()S`8e%y}fvzM;L}Q8VwxB$w9j`1xjL!CW<1AG5PnAQmz2;60ny8 zTrYckN>RxEtMc)~qD`r9Y->o2MP{=Bt+iNfQhuN907e+1SYyirOy6U<{bPTDKeCCl ze*5JRfsl|iB4+n3;+0A$M}kZpiE<3Z0gsX|AOYnHhBkwpil{AUj*biO%XiBU0#`iZ zfYufU%L0>VZrxj>x)^f%geLY&^sGG>l8EZWBtcIZ<+?flb%1#@%%T_p73T8L_VKOD zTYXF}=5K-B^IXQp4&gWs!^49_QJi1k{5-uZ=xhD1SS%u?pwWo%JRhYjaU8QSzkuU7 z1VKPwZ!hIii697Y90$j7sZV zaHvcv=Ens8aYVl8uDypx!|4Zt&D*xWs<*fIeL{$ZUpSzxg^_N>>|CAOA4pi$>mV&S zQJqkSXlrnk!0~-NPtk}09bz@~_FhI$-&Z+euSR7@>dMRqixo|Tt;KJ5+^*{}J)M?p z*Q^;OJBSeV3-2hDloSg^=I7@bA0MZ;x0m(n*Q1om0bQ+Dm#txvBp74xeILhhab0&A zSliDBY!}x{k@i{3lvJm(fMa;@_8VPF*%~>3QYxn)DY#{;c|Pk#AqTvb5+z(F$0ulL z&CKLM`VLN@T!XFPYfHAPC55DxJ zua1B5lkejNFTC8m_x*qK{zt?^8w+J0OxsS}2J zT%4X&gc0M~-*DKJ&t}+2 z0h+$H@B3)2bKn|daU3TTIVJgHeLo1$EGE%n-f4Pl?JoMlIR4f6f*bLZHH>g zjGoxkkst&z^zdE7Iluj(t^f8#`ur-FJoOnIt%P!H?2vdw0NoeBy+;kb#WH7}u1O+;;{{k{ zn5r${NQ)H`*OLg7dVyBcj@5$xRed;)OT8HpmmM%7A3?SJprED9M}DSdfYq?~n!hF4^+nv?5!P%vla1#+g>PSTZ5J^23kS5P z(!fHwlG;MZ!M!u|^p+SpEuln(un|G`TDk^?@hmhFgG>@U&tecHI3OfiM`-OMjLyAH z%Kh4TV%v6@HD$I6BOvl)D$<_~+E|h#S=y?BMx(*Hb?X=!8lqe-69fS|Z3@UeR10t| zE|~^s3fFb>n=JQeSz521q6i^~;~3BLxagvb&|0&wut2F)TETm5eiU8n^;UA^mHc?6 zw{Aa8w;j{R;`^=luGMOk%jMMbW}^z0&EB?cKZ_*?gazsP#9tOp_>Eu-@y~MK5aE{@Da#zq-mHa(sVm; z_J$JG$Z)V0u&RGM6hjOW*$j!Z`A6w<(l0uBWQrsXDfk7vG-bPVL{PTvE$ypIp4u3( zY~M`_dP|<&+BB!yq8&=6>8ln;b{vONsf1DrYb~zhl6HjX9OUh%1t_J`)La}d2c00z z_d2PUb{&^Ej%hZVl*{Fu3pjM@@;*cmzaHJrtFAz1Gd44%>yvjSSQjS(A zb>jxbtT8rytW+tji6TuHhD33=ET>&6mALcHJDHlAV#kghjE#-uUfFeBq?Gjb_7cZ& z?vb_DG@DI=AUHHz+GHiWO#TuzbSfpdeTZ;6l07AM9#^VD1==)uRPHR zVcKS4h)iFyJcTEv#7c=3GP^kp#$^6AyMe70$h5TwZ8WZOv-dJ7hZYuzBt5_?J1z-Tl5hydCZ7PLiM&5jY5wSzvJhGEb6LG~ZsM_0KEC+H?> zHn2wHxDLv5a9z0btDj?4Prz^e*~dtdI$h;5$>KDwA3zclHmby71D(X^I3`IVbP{3W zCP@@BKXZh*S<66d(OT!gH`%=CW+Ti*P_XDi}ry=iAZvqB7{IFi6d1m z2}tQv`n*^yNngU+B7?;N?*4z*a>x5$$>xhLW5-+m52cZAq=lpR&2Z?RIo|l(QO;kN z7PLP5g>O(AI*ogf3jG_-W5el>1;5PPo*UV9 z<2QNC(_Y58&wm|Zy$RM}w8kxTAsx_>MhcLQ;-BC7TJHGHKQpp^6Qe^tY}vGx-MjZN zHg=GA{OO;5<|$8o%3I<%DSY}fpZ>tUJrghO>l?`FLn}?Dvrh3fqutc&b+kzfI8hW+ ztJU)0@K^y^`mbP z%@)Nm^-7J&+y0qV-I{3U_j%yjAMw~fcn-D0FuuRR>h){5c%6%K6%g{Y?LF+f?_T7Z z3pwa3dflbwqa;aX#uq&2wM_hU7616&S8~fuH}j#7eE18OJ@Z9N9)$!!H;3;05kc(%qVZdq znRq(V^)N|@R37saJ88@u!YlV7F!XIa56ANf!zRrz#27=lT%uG=1Fs!Bw*PGV_8oJ; z+@HMTkAKo=hA-_CsfX_B>Y~5DAJ=s$mCC7R!3!vs%2;h#%sl4&{5(B9J;YJWefQnR zz`#HrB({6WRxTRS$wF})F+V?#wU&W_0cK}snV6Vh$BrFY>QLbq3KU9Zf&9y3sD&g>s`T{r;yw8aZg}TE;}4X0)*0Kdiz$8R8tG%UYN<66x|1nzTzsV{ zcl9%7WI8|ATC5SE!0&>d0m?X1>G1>#3$~CpLdG#l`KjKatDo-f&3K-haZ1a&3ohe<`ceF~kHhQg zCvGkx9T&gc%f26e4ina}Q4Oz9CaO;2mwPD&URu^Az1XEvk)EDj=H}<}?{2io(}hWr zP%4!e9UVnVNuf|6Nn(7@XJm9W$`Mp&DtzGJm-Ho|%~CmD>jcMfvs9nv z=;S0(6f-n5gfWJ>xjD+EQW^sk3h50YC08}6wNq+IKr6pXb5f6v&_ro;u6Kk zXaz}3Qfp8M0=l|WuD)2U5bFkxQbcir$+R!l7{W#!EJR5vrb1^~9M8pZ99EBvuxenC zW_;>xqo@&O5a;oskeOpK=OZw z1k@r!)e0tSmZGolltqvVZe*6CBJ&nXxhN@EIPw6xHp#%I^BCNIA$^<9rcf*r>lh97`ZQLr9;H#QQLR>qJieus^ z!stPYrDDdr)1a@}Y@)TLP%Kbyggp21m(bhS$9w+wA2Tv~8o%}HFQgRsRO@x-W@fqg zNl#(J#?8#m&M-4GO|?=biesHoFm>DQKV|>k-SiHhhBvs5D5`^r3B4wVckbe}#fYcA z^;d~&P@Mu*O7qL*e!=-})m@X$?7lMpq-bgOl|(Vmj~n^K1yy74Od*PqGk-rE_z;BwqzDFwAu zna4^?+d&ZIdk27WR30R@O5ECL>dht_hK5-)vYI4}nO|IBc5#-~U88BB8^u^@F%J3R z?90`EHs8{%u{e&(vJsZy;b9JD8I)>eo-La;(p4@Yvhuf-f|;3FW@l$J8Y0n3fl?^f z!;K?!ODU%{N~Ku_Au}$W?FuGIkXVYP0;|`YhU57hIp3Rm#)dWM7B5fU)BCf9!1gW_H z@X;xT`g@p}o5Kr&c_HL+=T*m1MBt|4uR;$fJDjHsIc+P=`C01YQ6?(@$1hUdeIK{} z)0;SW=M9{7#XC6nC4Y>H67Krgdr|XuGWWFK<4Lc5%^NR0v*$Y}l!W+2wDbreE%1gU zj{iK;M2WG)2Ade0#M+{buu)=kQ(GEQ%mq(c_j38$B zBOL`2JnbSAhe$U`gjsf2dy8A^BuPijW*)R9e(LS*rmwG;L>n6Q8d5oFLxAT{H;R&S z85!v3$kc4k*^?w94kJ9@%ZoU<_cZByI*yy)Jb9KwDUKW-=k}X#WMO`eX0u6mcP~kz z^JWFD4W)9|(8KC;jKLVd@sMQ@%_26_m0P1xmxHH5iNY z7%YyE)T@h(jIL*k9Oc9s1bxlvtFf)Gx z)@lwPon*0A$93IQ?wO=%M5R<)`Yr36aU7zkNum=R*Gsv3>pQtFVc6u(+iyebgxl(c(&X>%-G#OVfETgOioNNH+DBkTqg+1 z^sn8_{Nf^Mc2#703K!ePp{Hl2nVp?wbaV|u2*N02^~h?528SpV3RD-XXl?lQm%fyZ zn>KL6kAK3qzIAn)sfc5YFi0gcF~WmIKZ#CTrIbihQ!UzIl2iay3IeoE)qw{N9Atca zg24BQq6o+H@LV@73T65gZ46SmZKJS7eq%;aL=?q%u1gr{WeU9(rSZMAJ#1lqjxdag zleCK_Ng`IQ8W{Px3T9n{#FIPO^YP!~=%EKFb@!lA_{DCvz4Wh{gKvLJfMZZC?zTNt;X?+ zctMd;sem?p=p+*r36-U#Y^L#*7_IZ~{;X#`Yxm^jl%ANFP+=I-+uKWDUmrqgh>jE#-qx(>eYGrKSiSbDrJ>PdYWxLnswtAX0mY=#6*IuU}? zB|LCoAN%+3r?RksQj)+=TdrKsOO<*`Wxa@L@Epfc+6O6RuIp&=^;X4DDwXRtT7OR| zP=Zp0ltM)jNt_TT5mHFPM#QRtq0ygf-IW76CY(P=bz&#YSsz`Q!Y%Z%{iT17*V~J$ zAZ&uv;1prUi!b7|=U>Fk1bpW&KEd}t_&PS6HoW)apZwINy@PA)NpWzGc0fxhtmCMx zm|>Ap<-LVVa^SX;Wl5W9O#J_O@y0(raNvNqZQC}2 zARr1utg-C6|2}TH`9^%dK)GC|R;w*j^tFqbeBWnwc9w$=JiyVZY1WJkv2D{@gj6Ug zD0TPKkR_y0oO$jA{OJ4Fa^rvem^evD!f5%IT+yQ#h9Prv^QpG7JpflJ4{kOZ2rP|y z4Iw0n)>$#dVPIg8QmIUBu|jpR1}NfKGc|dXP20A!Vav8pJ$%zfI%`|#2E*q*n~`V! z5sh0ugF5%Oi0-)xZDR(uz*TSk2=ljol?$KpbmpoJCZ^_i>s#M&{_4Kc(I59ubiMr3 z|IqXN7rpfMo}QlQr0v*`en6{OwRMWLPw~k$4(+1$rE@-(sqsD6wZH`MPT-wi``Xu5 zz3W}?`YDLD#qKgm5);;&nQD5G+1XhJ2M5tQ?IIZ&8DZbPy^N1fP_0(E@1A>@o|~f? zM(o(WoyVN914k<67Uroe%=0@heDT`zFMPsyk|e_O0u{dT^>TW4#+jO)aci|&5J!>U zY&L^ht=3bo*Gsipt*g;!4ApD3!AiBdDvIOLdabr)c5Zg0vQQaaSXiK5ud6Uh+tm_n zXvR8~-6jcf6yg`V7+$+2y#b}m@JP(jBZs-;&bxTUOP+tzg_l0_S+46nY@Cw^&{hzX z`|tyU>^}`@=5dMvtIt@+kN^HV-1f0Ia{k$ysoZ%TV-M`*-uuQFe)ZFLUwFagOC8*= z`kj+YK_C5;L!=Yzb2+8WOUy04+3IXICT;P_hQl0JDgS~OykLfOo-!MEY-4C(6+=UV zTzJ6~4xD}VS>GEN82IU?O`Go3+8j!fIDXTc{_wzc*Zn)Lk|;00D|NAM!)DIdyq?vg zBM7PRf+E{TR&()_o_Nhg7eDb(8$MdK^6*60WBkZbQD3ZyW*Eva3}vHHSB+-VuU0Bf z7{#7cPFJJeD8|~9YKx0KKfeA4gO9)9{5zib^vizwb60<@!3zQw7v?#5*AIyj4Z>yU z(5DDSw(<3Myn%bZ@hQ%|;2c(Oc?>p+2nJ$$MiU~x@01>Z^viHgVVJ}pZU}$Kk*_=*zLtT5Bwo7SJ0rpd4vBTJ`yKS`2Nrq`v>A z)_cDFUEjt31gj^3mi7w_>dXZu)esCq!YIl*i?aU1LCkyy&@Z)=l)X02Y~xfmh9V*9 zrGR@}1bIoPaA$oZ*({xoMc#H!0$5q`Kf{g43|hvdcx5Svd^PN^Wm#$QdB2%-U>VZ? z%}@(}zi>$GAoGejUfTD!C9;%C67)nsdQxM(*l9ls^$J_)fAD}7LKrEf(Pj{LPW7fu z-yvi;U>@ap<(|OG!l%C&W6zu`RUL%+Ac>dM9>{$I~@9DP!6)*$R0?0^rJ^F%#gBw zudG)9`>wfehjP5+hmbNti2m4zEsqHS*%$>7$aK0VTI-$E_Z3@c-9HS46#YpBqEDFz zTdVtZ>f)se9CrXcWTB&;-0T)PSt3&hf!CdNWgJ=~kSMke69N#X_jgZ= zYB0;@m8Ki78bDi?6=|clOrAx;vEZp<%k~gPedA%mP64Fm0E0*agd(!s^FFD z)Ol3_S}7F`tbrVgXXpXIdx8Fpe#D91DNcGh99l|{S(}8&R8NNd@!?2^97sEauk?F+ zwREgR#+bg$*7jkO!xOTENQW5dB-ydhR|;sOv!)5rABB-!h^#JpnE08&V4=SSK)+fz zbU3Kx7?3xS4Vugf!%}@YAu&em)I+}<#-Rhv@O}Q;6g+@fWABq z9rt{Zl*bJ}D*DxS>1Z~E!4N0$j#GH$CORt-&5#R2pdOkY&>Jq4AzbcQ=*xEsMK8E- zQpa#G9yk+D%p69gQb~iI;-r^hq0@?^z7yD=FgtKn22LSqQGYs@Q0)NvGATzenDC?q zfqZ1<6mH8P3PBtvI~Mwi0vu-BMA=I`rw8tS$$`uwOuXWhz9Ip`!i;7&wHz0`qiau-QT96|5)<>2`uaWJ8Ke(vV&WDHxQH z7y(M{Sm?{%=PhYF!elBw0%Ob$hkiMJ%eIrSXQhWZNbk#3=tpn4PCI~pk>xl}kWPZS zgtyHgb7hjWVO9!BlI&RMmlNgKN|FbU4O?oBAu&3Onu@d$V+YVLy_8Zx-y&?;Wi!-4 zVbXDEJr2DC=qq*#dlPeqW73e;%Jh2cd#!Ku3;jVVwUb!6%;PWWS>oX$@}9n3e;6iu zV6E9vPWl_M(lAK07_-$07h($yltS**LtoZiIh6Wl3$IJVbUl6Oo&`@SN8;>2^GYqq zr9r*DXV93Qy-xE0QtnjST`r)*q4+Y}JHLBhrzu)MN)o*jhkm(E;dX01Oh3%vSnN+9 z6FY#u+$e{NWKU$fFIq67#nl|?!R`+aFp_oJu+5@V2Rr(@+ZEwl=yklCn-Ee1N1eI0Cg zlBxd0QHbL>NaaL3@VqiWZ|Bb2zaEtIrm=q|)ehyjObZ-?NE-(T;VWhqaQKKT)>Q5CrLt-=)R_Ls3Ae^ z0Q!n7^B^>8%!@sL0D9ZDUh%ztwdiuheUZjX9D}`3U7|JJC_w^oqUmZ$gtY_cE3nXM z7Ir|A(+Eg)BYCuEqziL5maxK}P+I5+ttKlYPnZ@c|%_q(i1#Z2Im@E#WGUQX zMra@bqAaaz133kjOa~X`l_qBkJeBr3MjB!bfdOTqRs(ZKY`8;fK{qkj!k`3nV}nWz zpLnjB2*E{Hs{37wrwSHN7nHe>lV;UbqUqZ*Xw){wo;>v2=X18L-t(>RWa0cNmX9Ae z1l;t>S?CnV{qFBLPUU2TKuCoYf+S8$4764xNt`+A0%ch{_0X5Ilv0V-I@NzLhHlU$ zj+1P*bcAg?xSmJYZc;mam@_Ailanzsd-k#ao4y0@rgy3@oasK;2*vF&DUGN&J>Y7z z+18pNAWYKINGSws9l=uDV9Bfy2e70-CW0W=I8tC+X@hPMr=GYgVaydM3H88WjHKck zd|OhFEY>@Y0yD3qd4FKU`!^zpLXAn%nqylSFcpe7yaT5MB^UPCP+JN2J#qH^-e^vR zyT|hS%7JS{qaE_4d+(-{_jt!U-(`A!NEBItWV4H~2_%!+XecbX-{tt4yu4nGe zw{z81`*3`lD2i{-DFx3PuAYs96I)5Sk$_Gmf^3yq=pODBgZb9l2wE|iIQ^a!f<^=i z!*VBmeI)>4sE2~0oes8?7+fh(Dt-Ma&k$-sJC?YLeq?%8ryhBuW)FlDmURx6X`S*S&dh}}#tMg}0&}uc4 zuYdW0@o&2Q9UBNilEfrNgR~J^A+!dQ&MH({Hdbqcl2JMWF01EIJCx(H-R@*=ZjRB> zQ4StF#IE^y#tI&%k3PdKZ@G=BJ=bt}wav(z--SE5n|-5GMBO$)k`OmH&{h%0cT%Mv z$P|AhMhq3C4teYeCIxeE($*y;-iBtmuzeDP-E)=tS-14bK_X~{1|@VhX&~kN0)eYQ z34xM^NTv6cB@K=;OnMRwv|^1CAU*JHhem{I#pY&=xH&Y?hz-ku=FCchHiG|lGD?&X zhjL2a9Y^6~3m48GtvW2+d3dq?__;Nu#^!m`4R2ua%t`h5qhI#`^0p*S5@c4(5hY1h zQJ2R0wa^%yV1PK58U09!no?@VLSN3Bn4C<)D5P6oCs{Z_e!9ZM>u#ela}yWlu4Cf0 zw{lekA_|GxP2z>~CO>>g=t- zF6fOoGh(=QI|aT&FASD`twajeNQ*Qbng}+->^-0{CQWeI%Alk{n6xfDXKN&2EAZ{q zk&R^9;E=P@Q>Y!IHbZlB$8fWs%Q1KTwJg*jN#LzNaT7!-|9?$n(Djvncd+v_e|X=c z2Rk|nuw4%{XrU4PI&*^-VlXwq7~&|(PBpN1;?S43HkZ#O(Z(Xy=seea-;d*5dkYr| zGn9*?#GN)vOUqbUcv>Nlw!*d@Y|BO}g^&uJ2^ zE!7|f4y72dm*IH%pgv-734dwG~n@q{Z+8DqGt){m_pO&uEk?`xItSYta)= z478ye3|>a-GKF>1N70qU+8~kyCDR)z4bkbW04d!!Ar(@k z6BK&8DXkqqzu;Qx#NynhzG|_V{6JlJKis@nXX(@_2x?eKj1i(A-0u&x&n$>i7Pjs5 zhj8|44btN}(=!%B6=Na`Ukq6rk>M&cP{_Vr-4?esg9%*n5|3XJv|@YT&9)v%@zTkU zE%ZigeQm|ozP~h6l*Y@uiH10vzAIAav>T_gUNTcaN_1+?jRF%VsBB-;5`#4IBcwp} zL#P^UG?o-Qlw5 z{V~bI15j*td9tn&3;4h39=WT$?t`;h*0b z*?UpBHL4;8at*^T)OT{X-A-nUTS{Mmu2+mNWLiURFllPrD1_%w8H3hho8u4PO&kVk znSo08+_5E=Wg%q>=yY^)3T7n?7dG0AP0#b@TfgalUO+#+9+%EF&HL(s_~pk|%)FyC zz5;3W@*RexS5uH(B}++^R0x?MjYexZ0E!Vvkxs!%L7j~tOLHfw8ju=-Ro3Kbvf-U( z*le1C8q-$rnwO{ze&Gkji^NMrc9)qfx-$4sVhcpKvXTKk%4!a`MP0W3CNs?2dxumG ziW5K$p8m{VA}<`rTR8=mo$jF$IF8i^b8p^?8S(@2xg3WMJ=}U{q(0ld)K|c z_+8&|#~%wJ)?f92KCqsYmOAEJSK8(yUtcyi+EU;tL0M%EjW!q~GB(hw6);+7b*E$_l9UH@FslfW$8VeWBRSq0{=HoMS^B+IDxOq7RmhI#b!Z1L8|jd?zq?~UTv!k^7{yPWQW78qMlo)P3U9KZVk9{Yo zo4bm*eh%y0ISQo_Ja-DMV|t|quf6fL6pBTb7MBnLT-RlBaS?!AE=Q-+A&erf-ghnE z_rCY=p6`Ay7woGz@zhsv&mUy{!trlex^PBL&hFO#AOZb}zxwX*wDna}{a@x2fB2g`e*fnQl|x~4f}EYFw$VUYibBq# zw!Vt%x@co4m&=TejdA|M1!m{w86B;1;=~DT+u^30UdN-4KEm4C8pUD}8ATj9a*Rs3 z!fP+AaQe*Ste<)Yr4-fKy;gN>d=yyu2MOq@94j-mXYLIjJ9YhPvpwDHgz^dHP^eB& znVKW9b3|4izg(qQE;BPbL#{fG>AdEpuflw;T3|eUsQr2zJ1GN?@3F#$6gxDIr=;adipi1M4t?LUu-()x0skQcK;2;aYURI9fd(a(CrY# zF$?F;u)KJI`T2R2vN&`46sFzg`kQZNW_Fh6o_&^+Cr|K}x7@}(_uPYJS$LjDtJUDI z?!1#Ho;tv{y?H-VGc(vqVEGlk_|-!{`q+VIKU>WE4a-)|oac2s&kcRoi9OHL-{67u zce{>0`?R`v;k>uJa52AGua!0%wXxbpZL-;FPj{o_7Qa;fK)EtbOE|dIDT))b1Xd2* z9HmMXH(w%OEMf#aw;HqDXw&L;skhsN?KZ+B*fK4&ca+4l6$RU-;M?Rqhl1~rb8TEp z4mmf2)~&u{*N;Cx-*W#=0NM;WXy(PPlo|TVn9I7dJ?9z6rZ5U#2pb0;=h@GFf&*W< zpOtpRwQqO}uY1ESxVA&5)x;ohTo=o+a2yY1IgE~t@$?gq@bJBNQmRx~Ti;-5agnL9 zF>-|>%C@LfDt!L)pXc`5--c3(yYIe>8*aFf$%!$}oH7Q?@{PT@7z-IxHa?9VcA zy!Y7I(_KaQ4h8M#47n`Vo?q!;BP)Xz9=lVmhu*BUhm-T%s5(ZR0AB@%#v~ zP$g7(+R{ZU8!aHzF&$-aZ5yM~Y@$J;h3Lnkw`3r;$8j&Euz5v57MF1F#0&q7xI_WS zOPHtrSZK$lI11h6h>eFH<;4A;;lVrq3hg*d?cT>5ckN|-Vut$0IeI!Ulyn?!3moi4j~?PBrbMLJ=~NY3ZN`SX-YCEj}b?HoS*3{z9n2q9VDsPk*T z__G9^HXr=ik8$MKiIfIK6HM=$!Opw<;cxvi(|h;x-tYZ>TJ;U$B&OBw%FTAjxy9A_ zZnHlB@PiNB_Cr7LkALVNWE^^}-f|aLH{PvAW|{HFaBT%>3b`C#d*B{UK6{Ay`Q50X zi5E2(@f>DJyi{;5L9Tm|Ugm00nK(rij>a%x|TROtUW6$tcci&H> zTs#S==Xv;^!@vLCKfv?zAPi^Eou}3AaPrhizS$dR?wWBX zrsgOW^K?5+q>@N!Qz@3vQNZ!T2RL=|7-x<@&1U1-HPC>9G;N&+WY!xx$x-2|^- zk;@qzKOv5nxp1n^!e)mBqi~BOj7-jwI0Zt-CqFVqxjII^>L49Ols01!g&-0TI-A#` z^-CQ6+Y3kqi4jPX-ay(wlw@@NlHuf`@SrjMM9_;xIgA10T9ikjakk0vFWyag?Kl&0 z9d~Sw$3sOkGE9w@w`tL7jMlU^>ujv8ki_vogF{Ii+o4!0XEaPvt8I`Zn(@g=beyoc z*&qx8sv}iw%OZ|r{CokeHMV83Qtyz|Lf&-y9X#^Ty_`9FjsqL(OkH&&Z@J?;`Q9J+ z071~D)oL+1K7sGL9DC*|o_yrXEG;h3YBdqYEd0<1K4AXd1Ny+T$KCS_%Xicot=~Ly z;_PdD&!b$(XZ60RJVEOCB&;l)v9B~F|?%f{Lo zQ5>Rmf^8{$KTok#WOjCz@$pf7-=mVxv$x`*lMu_Q<8F2dqnM4&Htj@E#~|H2cCJJV z7k_k$>eLj*Eh2Iy3KbvAQ)rQb-Dn^N9YYeQEzvRqWSU@r#AKzLb{cij1{_<{)q+r` zV|Ic>^i%ONi^Aw6<&|al-9>rzC~vH~1mi_c)qIXTbAhK0 zJk3a@v^9<{Qjj7+Sr)G6Z?8(hXhW;jL`sQe*(@$DA*Cdj%V7+hI&%i2HS6o^kF6+wv&GLNlHa+ zeJ!o)wQY>+Q7o3hXk5o8=jSPvO4MsLHa2QB8a0-dS827{wA)<}0?V}-8y#cMo;}RY z%_D`TzP7^j^c17jD#d&bM?g~FM75Tg_I=!B5xL>ejtuo6X2B@1JW8XJsC=20bg)ZR ziX&C>1EzF;?l}b@$7{fUw!Hz(k+s7YDAq)JU@rg2|DT` zEH{hGKi|O}j5tn{Qr-~IUDpL5ilVf4QwUIsrKLqiM@LiIkt7Hq@m+`Ii)UF`S)r15 zi8>ud#;36?iwE!dAKZHDt$f>eeh*)N@LryLb?! zDvx52N?s>)RNdqqRz+gO^kx{4} zU*+@{zsO!y=PkP{w9F)5Idq!O-Tze@?ST2YIcCR4IPmDEpxrIRjE|S`96o9c?Q>Y2&0I#jT&#i?Ha!2t#9Vw z;b)<{Nqv0zot>X!W@d(wkrB$}5_vDj%+v(soI)mb#-$)mBEs5v;<_Tfn5Toqxs4`) zuyOo6Zn4bB-og%7ckepllT4nufob19(no# zPG=3>SRve4Az404xOR@DRVQ9=Vxm^s(PP;N$41&N!p$KpC*5;7)L0-DIp1ZpI>K{D zj*=u1N=cr1?l?)3FgrO$&}q}ySi!Pv#-?ZZU#YjA3AdKV>!-Jpb0oq+EEjSbT0>KkWl**^s0ewML+6qrJzC6METN~z1;&8 z>g-rdUfzY76~~+7h39L#kvtI}0FtwK`|I$~@3{M~Ueqpn*WUIA@L#|6j>?#1>vOlZ z=m8?43QBC9L%QDz#l)*7tpuijkV54{NAHjaXCRV%;ao-Rd$!CXu3|nFPOypg=~kKm zuSLJ7f0X_~D;D9lHS1%TkF`VfEJ^%*&UR^&ImJ!OJyS$DCio)HghSu5hfK2)R|~Vo zE^h6o$8c(D@E6kL2#L_xC}?%s<#ddwt$#<@l7<`+p%JF53cT~MLr^1)qH*il- zF(%$+XJ1W5*6ali6YJZeh20N#Ka$gBsh6Tl;<~=!J&NA(&9`aFlBcqp%Tt!N$3qY8 z>)Q}4p!9!A5DaiSNOR|V+P#h)YT5CtP4`r&woU3XfiB+-qBrls@82@7QqQ275aUUk zXa|0Sdt=?3ez3;?>fX0A_#>wwiarez4Qgh7ZjpoU_m*{xXfZS#eezV==Pc}@k@LIs zyu7@ewkFr)q)hZD+R^UqN+4+|Z5j2Cso>O6Ao@t6<0c{HCdqDGJ$c#mp+??ye!Fq| zGeicxe`pA$TKm20Fg#vl#4&5Ees-Y$deLYK(D54@xD+Q8x7sO^;bzCH`h!i(u6Q%{ zFk->RKBetwA_yU~-de<5C20rrOXy;^L)`FszvaINr0%Cr-IIOWH0`&BFw(CcwEkTY zW~AHzM^aIn|#eV^q*WQ;&G>1U>Ec?J^$9y-Bc)&}qY-M)tX1<|8 zMZoy=Qx3Gkzuz3Md{%9={-=o8nj>3$y`lNaAOsXj#{da`+;7ZRVnj68a_`)BN}h;o zHq4LuLiL5Y*iO1(MlK$3X0#Wzty@+B7pK0hEoK2_to}i%PR~}an$Uzei7xnOnR*nk zDFH`9s{s}cx4sfDDJCx;>3~y`hzh4D2c*=1egsF0Rx@o zX}Mpcys@qot=cHell6$>vqRk4;<#D{g%rs7E?Hw~4*FXz(_r3oJI%{N{<4a)cE+$X zP@|0^V&q=52HMcvIx17GEV^d~x!aubO`*cb$ja(*1Nv~HmCFa8p2#3%PRC1V3=9m3 z>JF_8BK|Cy?Bqkd_A$CFS7C4VmX!9c^%+;(M=Vy6YyL}S*ZDO#>OEC zhrcHNXzynySNpXdxvTuT(|ZCrw*uS1XLH0E`T1I^XK2m-*~gDYHRE2>So^6 zA9*V(DRFTKNPuL1AMvc5U=7jn$3<%$vlDnkz_`I>w-E&to`K+WIM!}UWCcQ!lKSD+7g?xY{m+Kos%=@=z+gEwONrK zO$}5sDl;^6EzEmVQM;)}m=*&5KyQkyi`F{^{|mzrT$|e66>M1(9?M&X{OfpRKVi(1 z_rWQBb5Ew-I&h~M`tJ^G={tDf6OjAoH^?bz^HFry6xRg9*7gW^&3Am`>mnf+p{9rF zRz(cQQ3wwzVwd-=bTgE89zpq| zk6k>xqLa(`vI4$mkiYJy(lCxR`{Yk)PR~ejr?f2Z$zd6Eg>(OqmbpLDNoM$C)^nER zE{W{1RbKK4iin0Hj5UL`WFm_bG-R?`Bt-E?;7HcDwt7LP z4CF@umdM=P+|H#}NlK$0OIli*j-K9O@bsnd-@hJQ92^i(cvWrnoOKJAU<$C6m&~2u zFzVuJXzzeR5di{6+q{(P5OMJ7UV=Ja7-F?{w0vpb&J{>fPWy}YfAh9}Xw|W?zu8%s zF~H`)NRfKG6sTD{>!>_isWM&?Kf`z*UhV<|Y2_FgYLtD&J$5V1+d+mDct2xz?p?5!{)eq?}y z1!%<$>gEs^J6keoS;PE?6A}OZ>V+RYvY6P6+qSZ@<8RjU)6wf`3t&ly`~1yDB?)7N z_4`2_))=~$oNC0u3y?CnWf%$1yN5~jQBBiP@stdZcqr0|MR2i-*hsHz*LZIJ^QrLd z_}uvEiW1Z{Wkn{JDk8Hcj#G?p3@}>H*T;>i7u(w1{W`NhK>s9}h#q2WoVwv^2s9H^s>*cq?o6gc1;_17yn-bb91SWz_8q zI>-ZKFb>k9o0>dk6S$Q7Q=C~JySamVm~X{sp;S2VjQei=O6YN$_dVbkY)k}cC&sJF zD?CM2<5~26uu=6SJ)c;I@=)li+>A7raz;u5jkskWSEa36AC-k$b-zdFUXy{?k!pP5 z>IqIbN$y7{V=we6kDj`Od$P!ekVbk2h!5`AAWe;Z!_T&;p9Uq#FtsSDci5`T1WY@Z z*220UwbKcI-EP0VIbM-&O(<4dEf7>6bX!xnu!1>V-TF@54zQ6I4i%SUYL;)2r*p6t8oQ)AjN zQ=nbDwdcEjHI(hO@wgs-Bq;o_PuuaV50qndU6VJGu*8uGND>bL4>A<0+o;c?oGUo_ z&#>L|aWx=Iot|=7Dg6kz;n&@ND$n=% z6c2Z&ugh$clZv{fl6l}LUENhk>T>#aH?3nLj41IsR0GG5i^G%@6e8`&B!RN7Wyt{4crui4)U2eq;WNN z+-8J%;$uA)KIy7cojs|wfKGF+dopo?{H7r9giP+BOQiw7OBSr_MN2RjtG4yr!r{Vi zrJ6xS^c>vufFjW@jrVRqZFtRNW8!~p#}j-T1M7Z^=PIuU-R4_=n0T`>9oh~Ul0Lg^ z^$D=%i78|d`#+VxP|~5ri@gxzr#K zjx5=lXAFnh0JzLG<@eBKVtf-_dL*^CAA-_!@PgdKP1oU+ey`-d8`xdR!S7fdy=jY5 zJ)f51yR!Lb{sc_nbKCG37?r-nX%%V(Wbqro>d{@>4Tpw?&iwMV8I7S{p(@YI-=4RG zy06<`24SKPV+c&#Pkps7|B}~ce(-Q;pJ-If1AQ8UG=q|P>~gXv*EiL&*vWLg zmmQWyyamyNG`ph_WaQbzHvWpJL0Gc+eu6?MZy{vxy^Fgp6>Ia5k%|v8Kg@RCO9K%C zJXu3i7Iy9;U?9{aCqX=Y;A-_h&*?MXpcSp7FcIv!&JY{sHmxS^XBO+gNQWv28l@dS z?Tku1BsKv#A1-l>4x*bC!*~3`;jp-~4Kaaf*2SS|J2xF8L)thqG8hyP?EM!1?RByJ z0hAqc2Y8D~Br{)v^ zdgdzxgtFSC+DyZd<#2>dhuFtz8t6L-^I%c_`YX^DEk!f;l4wfEh0BGyC;VliR`}WI zW$xRbmt?WqncAEK*WIUMS8uaVkv}y$wHxe1q))@*;2FN60awsBD^59k=O0R$xA{#@ z=NBE%pLDlBbG6upxwi)|ppCtMpCjh?k)UmoS*uXfqC_wcx`Lkai8e+_S))2`%abAw zt`1H;bMe9n0!Ky$V>LYp<~o$u4#OWs7rSrV8taiEe5jeZ8xt=_4m)>sw7+d_|2VG- zWh}e#OiZ8{5AVIV<2{T~)~RA;!yn|p_PeLXBI6&vuI)tIy<`5`0pwaPCcg#n4Vq@U zH$ZAq!%|sUnSVC7Nls&e38RoD!l_Un2nBM4|-5UC>$s+ilg$G<5#S42bwu_$8iaAY1YFI*BQ($UAgM)5G zVAHAf%2^G@Vk`NImkFbfsmfh;;`O&QB5on#4@X)S+5F%zP`%Y+rYZA_Q@^|(STf-_DNm19j zSeaB7=5qN;_l%znA@%QF+YCR_(t@JBcx^DX7i>Q}4M)ydE^*ZlvBBLy3ZCHBy^VxnHOZlYb;JJ3hL^wt!@WgH81t^*VXUNwNGCu;!HA$3zhb1${ z<4QYyv`#<%M&+ zc*)})Z^_1K2?ma}Azjn8LA*h3eLZGlJSow=xj%o*OAI7%FISFg(QDh!C-T=`S{Xb} zx-VM-E*IBdx8h$O#qPH#@6&zv177_njXHWLpBGhJ_Lqw_Wq&9tDm!mIc`Ym~c&@Il zyKhTTK1_Fdthp_Yy}2SJ$oYCV(7gQL{P5l-^E)D41A_u}Cb21|m9~5DeI!g2KD|!S zE@tHU{}xq8ixNuJh}iPr;}!4_iS)xIe*9!E1AY&bRd;@u8;r}#_B)`PYGXKER!9G9 zpA)&vM}i_SLzGkyRmt2zQ81Ozq{f8hl*@8JzmnqQq{~yQ<=tWM?fLKGcp%#`tI>Z8 zuoKn6q&+yom(#9TlpUvJ+8S$)PHa=|8j`w zHJ=Zs8RU+PNc>MzRn{gX*Bx`8uGh_gW|XRZJj-pR@Gr~j(<5%FK;9D{rAgVgu&Hn(fH_e|7(HeX)?#C#!&zGsZ0SLGY`dA9~Ux=vzGrQzM90nfjU8akTeX0qHX zM_L;!!35Dyvuw|^MC;H0Ji5Q2;y%Ud>?@p$l!5?sU5K%3V-!w(fQiwsWtL=tgHM$9 ze!dNAdqde9Ju9PlviU-Nf1ZS!;Ry?fjq%R|Ky$$_Rv8loy!_)wIrK47H*ZQZS3UEayA$sEjIAB?OeFR1fnBM{ow=|4M` z$&Napx^1O{^!#EyUpVv+O2x_-@XMLiAa@!XsI#S+I6s9K(Pr zi9Q$w>cjk6)OoDESuXnI@=8Q`pSsaAwL7xsjEbl*HU>~1MIW~EU*|o#AJ@b_h5S0s zYZ-G!Z(0BbLk{AS{PlZN;~~)L2B91f5rKoznbM*R0{SrtEj zZEeT6c}b7gTJix{f1AW`Bpfy^UcO2ngQTsUrlb4yxSMUPo(U8UWQxfafyp0?DtSA7 z_bwr8SjOPAkAa1&2h%og2oj?CX!h0Pn(Tc3oB92* zbjOUq&DsUS%SEzB{mL0wr5Swe4w1~B623+-5^_V`ML$*^I5dmqU!#%O6JAzD1l$U5 z=OB53sU6Q$(pn$PfQv{K6O76CW(Dxfl1rbmhP$Z{F}FJ&zODnyjk_}a9}+EG8xAcV zj1Xs~3eEL^)#`6A=SFvDu$NUf-#fDnRl-MU#FI9M?th!xgVBnLigqsAtS7D5V&yQF zce0KQT%Veowe~Khu_%QDhl&M-3^loh+idHagX!0@Bv#*Htziksgc9_)^sYe;Rzr*eK%(cg8kpvmqCf@%o;ZU{Wuu-w5S-7(QPIVEulelvws(6!W7fVF&&))=a^Lw@ ze_J@Y?xsZRQ~L5w1k${iMd-c{clA zpLnc(-&OEeP4?dlLq4G{AF5MxqK`hH~(TO#EAGuh9GmyfJZbl6EF%^tV`y+VZD?$t|6k%=Hs4Ii zLixEGRo3Q&BSe*e3pL)`Dh@urvAa9e>@w-gP0ssY;xu1y%DyLf39b=dnwbImj2bbg zn9xKgwm%O`Ee~42Rd|5^(ZHWC-wgHjg>?XJ6S_VBn)3V03)8F^?R$+D`O>^y0v$H= zeaXU}!Ar~kA`=JP5|h1fQRuHx9L~S-3A!MD236 zbR5K1+5hHuJ)=^W2f|S`keMza?Y!EM3=EtW1>|#pppt)VY;37{VtgC}fJ=MkrI$9t z{pSs_Jv#+su2epQLS5U}{P&d^gIj6Sf54WoUbYGg^%2?L9ZpI*)Ln^Guq6(b`1sg0 z_MU?xCua`xEbDzqX%|R!Ysncnc&ZF?#hL2}!$DBR+t+WWE5YzzM~{~IEiE2CJ|2Q= z3JdU^VRt++b4G1P)10Lxv=17|(+JcdboPZT3BNlm)J^3x3rlg(?aSEd6fI^$EXxv< z`-@$zNEkL{1Lbu;&0)=Ju6qa+BxNa`}pWD zmVc_ED-O40q&g7`HRb$n^w7yJO=!xDTDKkg0cvamCH~t=Zd#nkZk)9*Pxte6bL#xA zI{-7uT&rWY6$y+TZ_{+<%fGpJWiz4TEhHx8+@*qteEwr1vI|`3=dU29R-4A2J|(H8 zb@%-8Ui9n9Me5>FC>_LDmoQWk@w+%etjrtHeC&GW{?l*Es~=G6tElkM`j291vM08d z>df{}PNZdJ-*ILF3WKCD#W%NMa7;{0qu%64tE^rC)WoeM#Z34H=9GpL0Z$k!Q~Sm} z-ENASX-6?{1Gpr8+=$dvk~m14onMK=!nok@jQp0r&DYo0g~i3df1OJDrT2GSTPsYI z4c7FDVxg6E+U=9+SUrYrTHz1EEz($*m7|*^h$* z-#^m;VlEDPD8OXsbt025#q-Q-8IVp?wp*@$TMipiW&MJ4@Kai4A#}CT8XpL+r|o!q z>zPM)ofS-%5Vf?N92{rWdLkic-PI?3_<{43jamI9BtD!6uG5@4m9V)3OFQ z4ByMF0hACmNo?QgtyCJ6JA1-NfqKP~vPD0*O1tqIWU5OTMAcZfmCTOWK+r@0j*79+ zaPX_ub?21+UUtMXMdxq7P~WgXh0(Kq^mcNxssN0KF`>t)9@eZb*pD!#%DyFC%@Ix2 zO%e7dQto50kXXh*CI|Y4S4jAus)CA~P<7_QQ#P@fycR<=BQ&Z#&G9`;6W&q&`yFgm zF#+_jbmK!UoDw2u4M}0bVDMeR0SQ*e-R0#Q>M65VmkktGB&ug4lzzVqs)#Rs`a2tP z`$x6iqR(gj*a0m0Q!v=jkYIUPnV>?c`WL_m<&qk23iMNMD}Ee)CX>J+J199BpVpUj z)Y8I@*2M}9euuqvwM5)kh*PuH@gZLH0Su76SDI{d;}UagS6~Hl=yS`~#9`lcg#YgR zxhay@(Bifs7~|V-agc!|ZNUXRg)z9R(c<97#0$yvsq%;jhu3Wlgur_eRm49ZUOJ1o zT3}rJj&KpqqDB5D?lO>WkhiyupxS;c^Ll< zCtgLVcPAz$Bx%$OW0%9`mdyP>U~}H}3C6l4VTH8B7{O2hMMVrL5R2?^g+@6*i2mvS z?43~-2@FgaOPab=e(6Yo^w{j^tT-l7Rl5{}74X`vdYAlNR6%IHr*9x=akMaHg=12k zIalH^Ea~~&xBqqi*R0sf4Gu%>=cK|Yo&SU^H~U7{K4{uZN8l%UW$l5CyA6ubb00rA zIHbEFB6Bo)`Ur()aRXTpBFT~^BtagHfPm!z`7EJn+<{{C;Xe(K%qyJR0=pBzh!eHi z9R=A0ll#_@!Zjpl+6}XuvB49*Q2pz%IhUWypTy^7hh^08_GNGl;WbyGg0h<-zTCMmQg(FqI6x2zsQffTJI6p)g5#=)K>5uG(qfUSG)C-l62 zE^Y9{sXeIADMzc$nsoNRmMXcMzz@CzLk&?|+3baX4DCPTv?idC%sW#Zp|6qvY)6t>)*KvoRkx)qD*7IL5m57x* zUQ#4~kOZO&P$Gb39}-W0Hkbc`VT%HwO!+7u_H!|mQeRcy#IR;gPgpeU+&&h9f8aa0 z8HQJZ+4Yt1(#odi)}D{g;jpfEn=V4`$5hU(IUa!TnmD%0t64dJBup`7FPeXfp0_t5 zPPOT}am-p`orT(DcLJPqiE_x--sI2E&!|x}03!1IneqweJUt9CsOL!%x7Qd)HlE_` zSUoW@anEv^?6T`Ukvcm?GBPs6Me||P(>UO$zODXnT&(aqz^qH=tbydJ ziK8Qq@Ko`P6>~);yOOvX4@QkqaN*H90_AD1ooMt7KI7T8f~;!A;gatJmFIf=^0L=& zQl1ofD5F;0Am2%oce{I+=axPG8c>UuK=;g>KiX5qf-rJ-1dp=*{6G6g~Hy_gKVlfxO)c|DYsOOxfARlRz(f_U9RbN7V zf#MNU@qZ+OeG-logl%QU?iP6U5yH~Q@L0Z=JxZF7ugW3H49T&dX(Ic>vCZ7w z7pyUbd`=SSFbw;%w4Qq@UpG_`5H^6ITFG|%&5(Yr<>B>1FyERhK986fB|smQOO-Fh zL~!>J&eKPhFb?kB^zz1oB;}kV)fZ9WMN$z)7k;g!#fuCq0s|?5&&6s3aHs!%L{(HU zRq50r0S^SQU!0Gr=w}^=kz+zO1H?g{G!s*A&;eWuB?4|O5dXm_2 zZoqjG)vQd_{tP9{y=*NToptj!oKs~=FZ_?BNbLx%VwjVAf@DS<2L*v7whYR*kcDRs zMG>Tx;L%dFK&4U$wy?UBe75>qp71>0ZPM02YAPJ*S@dRz;8Wu3hEV~p6Udbrt3mCJ z+$YEL4x&0M#w>OGg9GlGm7fQhw;Qj8K5v4$!=Qm*xX+#dG*4o_|ATci0PHuID@+wr zr$f}xIExc{xsu9%?xT%2IIIH@x(Yx(9}Vz&*HY!7KbP&+t%!&8pZo*HPj8a}E;P&i zjcikH`GxQ|5f1a^irCc&A~n#=+FC5Ybp&bz?N*yHGZj$)1OD}JSXt+NZ9~TIhyZwe zz|=mMKSM;eN2F!*(-AVCJ^8W7$#J<$7~&`duyA^A>=)sFr`?pfqs4?*A6be_}iYkg(FggpJp(ukNH!wKo(jZSi4~BtajbBPH7xuZIHC5FomVR zRJ-GFjXDMfMh|zj1iPW3;U@ni)716tZE<<|J7C3!cb%6St&=ZXx*^4VjSC3)8fm8q zd-bZCZ@DK5v_F}hw7JQ-UQ_4hAwn7g3tJexczf!}_~TkoC|3GCS&O2n(U6#>Xh>oa z+oGP|VVS~*VwFdx<&97SIXB@fq}ffWbtr~>CRyCBxq&qt(>(Yn<_XMi7&2`}U>H5B z)KgDL3}fG;s^3C?BhI3eWI0gbVHN7u7Pd3a|FXDrQ!&ZhBES_)mG8tbu4W#aBzv#$ zr$!=;UXw6t|KP;u;Pzf7-wSA75%0PdMBc3H^tr`LPEPJyTGE+1KCU94@VFGF#7F+V z<3)kd9|Zltot?yWK1@Pmmb!nONet|e82y_owzY0H`$UJwP56@x1;jWxje#cBAW1C( zGU1<;bV^cusE#REMpS{$_6rBxc|uq#&3(TDb;kP()%Cvqd^y*gCfIU=Wh*f1&DYJ<^-83fane~jIzonasD1tZ=G5bQ9cn`(!9*J|M*=u+m=-R&$B)0oLfU;Eq5?o6&2<5M*H7RcLGO{u^vz@$rcXw0qw!#$07=LiEs+wwlwwUR@d>>7+d` zM>3B*QlC289n+bIAZtn60f`1CDK#xre=(~p!Kp3hil0Z1?xEJ_n0p$h_QY0NXdi^W0xA7wVwq8x_x9yrq*io1_3fH80+{_>sM#GO* zVg%f4JvY^h5bMKe&)Rfj2jKB^_6 z3sgw-MHe+lyuzS2%{J)4ZB^4D}pd_$1CqLh# zNMNkql?unv`O>|JP5Nd-$HP9BR-t?joc_sJ_sFwZFQLp@7S;XhMgfauGxX<)Si@^T ztAUJ>5&F0FbD5Yp3criUZ@zn7yS{6NlHFltnBRedL8C}z?kip z?6MCHGUE@_s7Ri9uRJH$gL2Aqjino5k@BVJx^*NxKg#s_*?8tTn@AQE36hX~Me|*_ zmMfyFF&c}TYmTNd@xOJLys!D18dP>vdEF?Z z-NDxv`tL)%fQ#+pRszQIsDW5KgvWxQx-ecwRK(AMK{%bqcj=S?7g4+ZEQXS78bGB< z@n?o)TuTcJZ&@IK-23}?eci57>%+eGo+$Hs{=N6KNNY5k*g;QEjY2-F5{H^;iO>xeN>-7{fq z37j5wZkoa#d%$LTU!BoTwr``JA8#A_`}^w-4h}v6?F#KcspDZVnWeqQENzDkzw=JSDZmM>3GFwDC_+txlDknU%_R^JoKLbpXb-US`u`1|dbxFJ zXWP9iv-YNk92Q!8=RkE&oPRMiDnySF(LqL$C3MobY8N?ZH9rFLHf7QV8)@Kok;xHZ zgFW=JLO}@#IUPAQkqY}`#9NL!*vLqLPey;@oFigB#QEprf0~M_pzo8DlRZb<3?9}_ z_cV!e85Np8bgQ-1Dl`FwGTf%=kXu%9j&u7kE2_p^-4*S`bQ%7mvPNECXzSyD^EL@| zBOksS^C`GW_l~B1K?QD$*@rH9q~T^<#HVJ>G!Xd4(LoU`fHo2Q$dKjbWovg=*NpGtJ;=s2@@_;!%DJ9~AOvta zUOFFz&vD)8d$x`&4036)};g`}re2yQ Date: Wed, 30 Nov 2022 15:36:10 +0100 Subject: [PATCH 42/99] RatRig - sync with PrusaSlicer-settings --- resources/profiles/RatRig.idx | 1 + resources/profiles/RatRig.ini | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/profiles/RatRig.idx b/resources/profiles/RatRig.idx index f0c1174647..b8811aa5e8 100644 --- a/resources/profiles/RatRig.idx +++ b/resources/profiles/RatRig.idx @@ -1,3 +1,4 @@ min_slic3r_version = 2.4.1-alpha0 +1.0.2 Updated start g-code. 1.0.1 Various fixes and improvements. Commented filament sensor initialisation for v-Minion (optional HW). 1.0.0 Initial RatRig bundle \ No newline at end of file diff --git a/resources/profiles/RatRig.ini b/resources/profiles/RatRig.ini index 5558cf6989..56fab6e0df 100644 --- a/resources/profiles/RatRig.ini +++ b/resources/profiles/RatRig.ini @@ -9,7 +9,7 @@ name = RatRig # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the Slic3r configuration to be downgraded. -config_version = 1.0.1 +config_version = 1.0.2 # Where to get the updates from? config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/RatRig/ # The printer models will be shown by the Configuration Wizard in this order, @@ -433,7 +433,7 @@ retract_restart_extra_toolchange = 0 retract_speed = 40 silent_mode = 0 single_extruder_multi_material = 0 -start_gcode = M190 S0 ; Prevents prusaslicer from prepending m190 to the gcode interfering with the macro\nM109 S0 ; Prevents prusaslicer from prepending m109 to the gcode interfering with the macro\nSTART_PRINT EXTRUDER_TEMP=[first_layer_temperature] BED_TEMP=[first_layer_bed_temperature]\n;enable this if you have a BTT Smart Filament Sensor\nSET_FILAMENT_SENSOR SENSOR=my_sensor ENABLE=0\n +start_gcode = M190 S0 ; Prevents prusaslicer from prepending m190 to the gcode interfering with the macro\nM109 S0 ; Prevents prusaslicer from prepending m109 to the gcode interfering with the macro\nSET_GCODE_VARIABLE MACRO=RatOS VARIABLE=relative_extrusion VALUE=True\nSTART_PRINT EXTRUDER_TEMP=[first_layer_temperature] BED_TEMP=[first_layer_bed_temperature]\n;enable this if you have a BTT Smart Filament Sensor\nSET_FILAMENT_SENSOR SENSOR=my_sensor ENABLE=0\n thumbnails = 64x64,400x300 toolchange_gcode = use_firmware_retraction = 0 @@ -496,7 +496,7 @@ retract_restart_extra_toolchange = 0 retract_speed = 40 silent_mode = 0 single_extruder_multi_material = 0 -start_gcode = M190 S0 ; Prevents prusaslicer from prepending m190 to the gcode interfering with the macro\nM109 S0 ; Prevents prusaslicer from prepending m109 to the gcode interfering with the macro\nSTART_PRINT EXTRUDER_TEMP=[first_layer_temperature] BED_TEMP=[first_layer_bed_temperature]\n;enable this if you have a BTT Smart Filament Sensor\n; SET_FILAMENT_SENSOR SENSOR=my_sensor ENABLE=0\n +start_gcode = M190 S0 ; Prevents prusaslicer from prepending m190 to the gcode interfering with the macro\nM109 S0 ; Prevents prusaslicer from prepending m109 to the gcode interfering with the macro\nSET_GCODE_VARIABLE MACRO=RatOS VARIABLE=relative_extrusion VALUE=True\nSTART_PRINT EXTRUDER_TEMP=[first_layer_temperature] BED_TEMP=[first_layer_bed_temperature]\n;enable this if you have a BTT Smart Filament Sensor\nSET_FILAMENT_SENSOR SENSOR=my_sensor ENABLE=0\n start_gcode_manual = 0 template_custom_gcode = thumbnails = 64x64,400x300 From b51d478031b0256926b38860c837402ead2a6714 Mon Sep 17 00:00:00 2001 From: rtyr <36745189+rtyr@users.noreply.github.com> Date: Wed, 30 Nov 2022 16:10:32 +0100 Subject: [PATCH 43/99] Anker - disabled thick bridges https://github.com/prusa3d/PrusaSlicer/pull/9195 --- resources/profiles/Anker.idx | 1 + resources/profiles/Anker.ini | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/profiles/Anker.idx b/resources/profiles/Anker.idx index 4a988bbdff..49e15b3d03 100644 --- a/resources/profiles/Anker.idx +++ b/resources/profiles/Anker.idx @@ -1,2 +1,3 @@ min_slic3r_version = 2.6.0-alpha1 +1.0.1 Disabled thick bridges. 1.0.0 Initial Version diff --git a/resources/profiles/Anker.ini b/resources/profiles/Anker.ini index c7408f6e4d..34592e1e55 100644 --- a/resources/profiles/Anker.ini +++ b/resources/profiles/Anker.ini @@ -6,7 +6,7 @@ name = Anker # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 1.0.0 +config_version = 1.0.1 # Where to get the updates from? config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anker/ @@ -118,7 +118,7 @@ support_material_synchronize_layers = 0 support_material_threshold = 40 support_material_with_sheath = 0 support_material_xy_spacing = 60% -thick_bridges = 1 +thick_bridges = 0 thin_walls = 0 top_solid_infill_speed = 150 travel_speed = 300 From ba8b81b27e03ec4dda329034b0d42e586b5d0f49 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 1 Dec 2022 11:08:33 +0100 Subject: [PATCH 44/99] Cut: Extension for delete parts from cut objects. When try to delete something from the cut object, than not just inform the users about an impossibility of this action, but allow them to invalidate a cut information or delete all connectors from related objects, but leave the cut info. --- src/libslic3r/Model.cpp | 16 ++++ src/libslic3r/Model.hpp | 4 + src/slic3r/GUI/GUI_ObjectList.cpp | 122 +++++++++++++++++++++++------- src/slic3r/GUI/GUI_ObjectList.hpp | 5 +- src/slic3r/GUI/Plater.cpp | 2 +- 5 files changed, 121 insertions(+), 28 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index b328dbf28b..76668d0d2b 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1279,6 +1279,14 @@ void ModelObject::invalidate_cut() volume->invalidate_cut_info(); } +void ModelObject::delete_connectors() +{ + for (int id = int(this->volumes.size()) - 1; id >= 0; id--) { + if (volumes[id]->is_cut_connector()) + this->delete_volume(size_t(id)); + } +} + void ModelObject::synchronize_model_after_cut() { for (ModelObject* obj : m_model->objects) { @@ -1994,6 +2002,14 @@ int ModelObject::get_repaired_errors_count(const int vol_idx /*= -1*/) const stats.facets_reversed + stats.backwards_edges; } +bool ModelObject::has_solid_mesh() const +{ + for (const ModelVolume* volume : volumes) + if (volume->is_model_part()) + return true; + return false; +} + void ModelVolume::set_material_id(t_model_material_id material_id) { m_material_id = material_id; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index d514171f17..6fb2bc923d 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -449,6 +449,8 @@ public: void apply_cut_connectors(const std::string& name); // invalidate cut state for this object and its connectors/volumes void invalidate_cut(); + // delete volumes which are marked as connector for this object + void delete_connectors(); void synchronize_model_after_cut(); void apply_cut_attributes(ModelObjectCutAttributes attributes); void clone_for_cut(ModelObject **obj); @@ -482,6 +484,8 @@ public: // Get count of errors in the mesh( or all object's meshes, if volume index isn't defined) int get_repaired_errors_count(const int vol_idx = -1) const; + // Detect if object has at least one solid mash + bool has_solid_mesh() const; bool is_cut() const { return cut_id.id().valid(); } bool has_connectors() const; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 127d97caa2..8c15464100 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1880,6 +1880,7 @@ bool ObjectList::del_subobject_item(wxDataViewItem& item) wxDataViewItem parent = m_objects_model->GetParent(item); + InfoItemType item_info_type = m_objects_model->GetInfoItemType(item); if (type & itSettings) del_settings_from_config(parent); else if (type & itInstanceRoot && obj_idx != -1) @@ -1889,7 +1890,7 @@ bool ObjectList::del_subobject_item(wxDataViewItem& item) else if (type & itLayer && obj_idx != -1) del_layer_from_object(obj_idx, m_objects_model->GetLayerRangeByItem(item)); else if (type & itInfo && obj_idx != -1) - del_info_item(obj_idx, m_objects_model->GetInfoItemType(item)); + del_info_item(obj_idx, item_info_type); else if (idx == -1 || !del_subobject_from_object(obj_idx, idx, type)) return false; @@ -1898,9 +1899,12 @@ bool ObjectList::del_subobject_item(wxDataViewItem& item) const std::string& icon_name = get_warning_icon_name(object(obj_idx)->get_object_stl_stats()); m_objects_model->UpdateWarningIcon(parent, icon_name); } - m_objects_model->Delete(item); - update_info_items(obj_idx); + if (!(type & itInfo) || item_info_type != InfoItemType::CutConnectors) { + // Connectors Item is already updated/deleted inside the del_info_item() + m_objects_model->Delete(item); + update_info_items(obj_idx); + } return true; } @@ -1926,7 +1930,10 @@ void ObjectList::del_info_item(const int obj_idx, InfoItemType type) break; case InfoItemType::CutConnectors: - show_error(nullptr, _L("Connectors cannot be deleted from cut object.")); + if (!del_from_cut_object(true)) { + // there is no need to post EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS if nothing was changed + return; + } break; case InfoItemType::MmuSegmentation: @@ -2018,6 +2025,38 @@ void ObjectList::del_layers_from_object(const int obj_idx) changed_object(obj_idx); } +bool ObjectList::del_from_cut_object(bool is_cut_connector, bool is_model_part/* = false*/, bool is_negative_volume/* = false*/) +{ + const long buttons_style = is_cut_connector ? (wxYES | wxNO | wxCANCEL) : (wxYES | wxCANCEL); + + const wxString title = is_cut_connector ? _L("Delete connector from object which is a part of cut") : + is_model_part ? _L("Delete solid part from object which is a part of cut") : + is_negative_volume ? _L("Delete negative volume from object which is a part of cut") : ""; + + const wxString msg_end = is_cut_connector ? ("\n" + _L("To save cut correspondence you can delete all connectors from all related objects.")) : ""; + + InfoDialog dialog(wxGetApp().plater(), title, + _L("This action will break a cut correspondence.\n" + "After that PrusaSlicer can't guarantee model consistency.\n" + "\n" + "To manipulate with solid parts or negative volumes you have to invalidate cut infornation first." + msg_end ), + false, buttons_style | wxCANCEL_DEFAULT | wxICON_WARNING); + + dialog.SetButtonLabel(wxID_YES, _L("Invalidate cut info")); + if (is_cut_connector) + dialog.SetButtonLabel(wxID_NO, _L("Delete all connectors")); + + const int answer = dialog.ShowModal(); + if (answer == wxID_CANCEL) + return false; + + if (answer == wxID_YES) + invalidate_cut_info_for_selection(); + else if (answer == wxID_NO) + delete_all_connectors_for_selection(); + return true; +} + bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type) { assert(idx >= 0); @@ -2039,15 +2078,10 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con Slic3r::GUI::show_error(nullptr, _L("From Object List You can't delete the last solid part from object.")); return false; } - if (object->is_cut()) { - if (volume->is_model_part()) { - Slic3r::GUI::show_error(nullptr, _L("Solid part cannot be deleted from cut object.")); - return false; - } - if (volume->is_negative_volume()) { - Slic3r::GUI::show_error(nullptr, _L("Negative volume cannot be deleted from cut object.")); - return false; - } + if (object->is_cut() && (volume->is_model_part() || volume->is_negative_volume())) { + del_from_cut_object(volume->is_cut_connector(), volume->is_model_part(), volume->is_negative_volume()); + // in any case return false to break the deletion + return false; } take_snapshot(_L("Delete Subobject")); @@ -2489,6 +2523,7 @@ bool ObjectList::has_selected_cut_object() const return false; } + void ObjectList::invalidate_cut_info_for_selection() { const wxDataViewItem item = GetSelection(); @@ -2499,27 +2534,61 @@ void ObjectList::invalidate_cut_info_for_selection() } } -void ObjectList::invalidate_cut_info_for_object(size_t obj_idx) +void ObjectList::invalidate_cut_info_for_object(int obj_idx) { - ModelObject* init_obj = object(int(obj_idx)); + ModelObject* init_obj = object(obj_idx); if (!init_obj->is_cut()) return; take_snapshot(_L("Invalidate cut info")); - auto invalidate_cut = [this](size_t obj_idx) { - object(int(obj_idx))->invalidate_cut(); - update_info_items(obj_idx); - add_volumes_to_object_in_list(obj_idx); - }; - + const CutObjectBase cut_id = init_obj->cut_id; // invalidate cut for related objects (which have the same cut_id) for (size_t idx = 0; idx < m_objects->size(); idx++) - if (ModelObject* obj = object(idx); obj != init_obj && obj->cut_id.is_equal(init_obj->cut_id)) - invalidate_cut(idx); + if (ModelObject* obj = object(int(idx)); obj->cut_id.is_equal(cut_id)) { + obj->invalidate_cut(); + update_info_items(idx); + add_volumes_to_object_in_list(idx); + } - // invalidate own cut information - invalidate_cut(size_t(obj_idx)); + update_lock_icons_for_model(); +} + +void ObjectList::delete_all_connectors_for_selection() +{ + const wxDataViewItem item = GetSelection(); + if (item) { + const int obj_idx = m_objects_model->GetObjectIdByItem(item); + if (obj_idx >= 0) + delete_all_connectors_for_object(size_t(obj_idx)); + } +} + +void ObjectList::delete_all_connectors_for_object(int obj_idx) +{ + ModelObject* init_obj = object(obj_idx); + if (!init_obj->is_cut()) + return; + + take_snapshot(_L("Delete all connectors")); + + const CutObjectBase cut_id = init_obj->cut_id; + // Delete all connectors for related objects (which have the same cut_id) + Model& model = wxGetApp().plater()->model(); + for (int idx = int(m_objects->size())-1; idx >= 0; idx--) + if (ModelObject* obj = object(idx); obj->cut_id.is_equal(cut_id)) { + obj->delete_connectors(); + + if (obj->volumes.empty() || !obj->has_solid_mesh()) { + model.delete_object(idx); + m_objects_model->Delete(m_objects_model->GetItemById(idx)); + continue; + } + + update_info_items(idx); + add_volumes_to_object_in_list(idx); + changed_object(int(idx)); + } update_lock_icons_for_model(); } @@ -3044,6 +3113,7 @@ bool ObjectList::delete_from_model_and_list(const std::vector& it return false; m_prevent_list_events = true; + ScopeGuard sg_prevent_list_events = ScopeGuard([this]() { m_prevent_list_events = false; }); std::set modified_objects_ids; for (std::vector::const_reverse_iterator item = items_for_delete.rbegin(); item != items_for_delete.rend(); ++item) { @@ -3059,7 +3129,7 @@ bool ObjectList::delete_from_model_and_list(const std::vector& it } else { if (!del_subobject_from_object(item->obj_idx, item->sub_obj_idx, item->type)) - continue; + return false;// continue; if (item->type&itVolume) { m_objects_model->Delete(m_objects_model->GetItemByVolumeId(item->obj_idx, item->sub_obj_idx)); ModelObject* obj = object(item->obj_idx); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 9cd3dc8e17..d2965c77e3 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -266,6 +266,7 @@ public: void del_instances_from_object(const int obj_idx); void del_layer_from_object(const int obj_idx, const t_layer_height_range& layer_range); void del_layers_from_object(const int obj_idx); + bool del_from_cut_object(bool is_connector, bool is_model_part = false, bool is_negative_volume = false); bool del_subobject_from_object(const int obj_idx, const int idx, const int type); void del_info_item(const int obj_idx, InfoItemType type); void split(); @@ -282,7 +283,9 @@ public: bool can_split_instances(); bool has_selected_cut_object() const; void invalidate_cut_info_for_selection(); - void invalidate_cut_info_for_object(size_t obj_idx); + void invalidate_cut_info_for_object(int obj_idx); + void delete_all_connectors_for_selection(); + void delete_all_connectors_for_object(int obj_idx); bool can_merge_to_multipart_object() const; bool can_merge_to_single_object() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e11e08d043..e31f9ec61c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3001,7 +3001,7 @@ bool Plater::priv::delete_object_from_model(size_t obj_idx) InfoDialog dialog(q, _L("Delete object which is a part of cut object"), _L("You try to delete an object which is a part of a cut object.\n" "This action will break a cut correspondence.\n" - "After that PrusaSlicer can't garantie model consistency"), + "After that PrusaSlicer can't guarantee model consistency"), false, wxYES | wxCANCEL | wxCANCEL_DEFAULT | wxICON_WARNING); dialog.SetButtonLabel(wxID_YES, _L("Delete object")); if (dialog.ShowModal() == wxID_CANCEL) From f7c832ddafd59947106cc8e49cc05ccf21ed3135 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 1 Dec 2022 12:37:34 +0100 Subject: [PATCH 45/99] Fix crash when pressing 'A' without any objects on plater --- src/slic3r/GUI/Jobs/ArrangeJob.cpp | 9 ++++++--- src/slic3r/GUI/Plater.cpp | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 9e62283e38..7214ccdaba 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -165,8 +165,6 @@ void ArrangeJob::process(Ctl &ctl) { static const auto arrangestr = _u8L("Arranging"); - ctl.update_status(0, arrangestr); - arrangement::ArrangeParams params; Points bedpts; ctl.call_on_main_thread([this, ¶ms, &bedpts]{ @@ -175,7 +173,12 @@ void ArrangeJob::process(Ctl &ctl) bedpts = get_bed_shape(*m_plater->config()); }).wait(); - auto count = unsigned(m_selected.size() + m_unprintable.size()); + auto count = unsigned(m_selected.size() + m_unprintable.size()); + + if (count == 0) // Should be taken care of by plater, but doesn't hurt + return; + + ctl.update_status(0, arrangestr); params.stopcondition = [&ctl]() { return ctl.was_canceled(); }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e31f9ec61c..e73eedfebd 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4977,7 +4977,7 @@ bool Plater::priv::can_split_to_volumes() const bool Plater::priv::can_arrange() const { - if (model.objects.empty() && m_worker.is_idle()) return false; + if (model.objects.empty() || !m_worker.is_idle()) return false; if (q->canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::Emboss) return false; return true; } @@ -6821,8 +6821,8 @@ GLCanvas3D* Plater::get_current_canvas3D() void Plater::arrange() { - auto &w = get_ui_job_worker(); - if (w.is_idle()) { + if (p->can_arrange()) { + auto &w = get_ui_job_worker(); p->take_snapshot(_L("Arrange")); replace_job(w, std::make_unique()); } From 85195ac79fb2b7016b05ffff5eb33a483a4d06c2 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 1 Dec 2022 12:47:06 +0100 Subject: [PATCH 46/99] Measure gizmo - Fixed sychronization of imgui dialog with current hovering/selection state --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 94 +++++++++++++++++++++--- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 4ce33f7cfe..2b848bd985 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1828,22 +1828,61 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ColorRGBA color; if (m_selected_features.second.feature.has_value()) { if (m_selected_features.first.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { + // hovering over 1st selected feature text = _u8L("Unselect feature"); color = SELECTED_1ST_COLOR; } + else if (m_hover_id == SEL_SPHERE_1_ID) { + if (m_selected_features.first.is_center) { + // hovering over center selected as 1st feature + text = _u8L("Unselect center"); + color = SELECTED_1ST_COLOR; + } + else if (is_feature_with_center(*m_selected_features.first.feature)) { + // hovering over center of 1st selected feature + text = _u8L("Select center"); + color = SELECTED_1ST_COLOR; + } + else { + // hovering over point selected as 1st feature + text = _u8L("Unselect point"); + color = SELECTED_1ST_COLOR; + } + } + else if (m_selected_features.first.is_center && m_selected_features.first.source == m_curr_feature) { + // hovering over feature whose center is selected as 1st feature + text = _u8L("Select feature"); + color = SELECTED_1ST_COLOR; + } else if (m_selected_features.second.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { + // hovering over 2nd selected feature text = _u8L("Unselect feature"); color = SELECTED_2ND_COLOR; } - else if (m_hover_id == SEL_SPHERE_1_ID) { - text = _u8L("Unselect point"); - color = SELECTED_1ST_COLOR; - } else if (m_hover_id == SEL_SPHERE_2_ID) { - text = _u8L("Unselect point"); + if (m_selected_features.second.is_center) { + // hovering over center selected as 2nd feature + text = _u8L("Unselect feature"); + color = SELECTED_2ND_COLOR; + } + else if (is_feature_with_center(*m_selected_features.second.feature)) { + // hovering over center of 2nd selected feature + text = _u8L("Select center"); + color = SELECTED_2ND_COLOR; + } + else { + // hovering over point selected as 2nd feature + text = _u8L("Unselect point"); + color = SELECTED_2ND_COLOR; + } + } + else if (m_selected_features.second.is_center && m_selected_features.second.source == m_curr_feature) { + // hovering over feature whose center is selected as 2nd feature + text = _u8L("Select feature"); color = SELECTED_2ND_COLOR; } else { + // 1st feature selected text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); color = SELECTED_2ND_COLOR; } @@ -1851,20 +1890,51 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit else { if (m_selected_features.first.feature.has_value()) { if (m_selected_features.first.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { + // hovering over 1st selected feature text = _u8L("Unselect feature"); color = SELECTED_1ST_COLOR; } - else if (m_hover_id == SEL_SPHERE_1_ID) { - text = _u8L("Unselect point"); - color = SELECTED_1ST_COLOR; + else { + if (m_hover_id == SEL_SPHERE_1_ID) { + if (m_selected_features.first.is_center) { + // hovering over center selected as 1st feature + text = _u8L("Unselect feature"); + color = SELECTED_1ST_COLOR; + } + else if (is_feature_with_center(*m_selected_features.first.feature)) { + // hovering over center of 1st selected feature + text = _u8L("Select center"); + color = SELECTED_1ST_COLOR; + } + else { + // hovering over point selected as 1st feature + text = _u8L("Unselect point"); + color = SELECTED_1ST_COLOR; + } + } + else { + if (m_selected_features.first.is_center && m_selected_features.first.source == m_curr_feature) { + // hovering over feature whose center is selected as 1st feature + text = _u8L("Select feature"); + color = SELECTED_1ST_COLOR; + } + else { + // 1st feature selected + text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); + color = SELECTED_2ND_COLOR; + } + } } } - if (text.empty()) { + else { + // nothing is selected text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); - color = m_selected_features.first.feature.has_value() ? SELECTED_2ND_COLOR : SELECTED_1ST_COLOR; + color = SELECTED_1ST_COLOR; } } + assert(!text.empty()); + m_imgui->text_colored(ImGui::GetStyleColorVec4(ImGuiCol_Text), text); ImGui::SameLine(); const ImVec2 pos = ImGui::GetCursorScreenPos(); @@ -1982,7 +2052,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit if (use_inches) distance = ObjectManipulation::mm_to_in * distance; ImGui::PushID("ClipboardDistanceInfinite"); - add_measure_row_to_table(_u8L("Distance Infinite"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(distance) + units, + add_measure_row_to_table(_u8L("Distance"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(distance) + units, ImGui::GetStyleColorVec4(ImGuiCol_Text)); ++measure_row_count; ImGui::PopID(); @@ -1993,7 +2063,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit if (use_inches) distance = ObjectManipulation::mm_to_in * distance; ImGui::PushID("ClipboardDistanceStrict"); - add_measure_row_to_table(_u8L("Distance Strict"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(distance) + units, + add_measure_row_to_table(_u8L("Distance"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(distance) + units, ImGui::GetStyleColorVec4(ImGuiCol_Text)); ++measure_row_count; ImGui::PopID(); From 1974a56fab76357a6752b106a8e0554b8de1a844 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 1 Dec 2022 13:31:22 +0100 Subject: [PATCH 47/99] Measurement: tweaking of the tolerances, ransacing the whole border --- src/libslic3r/Measure.cpp | 324 ++++++++++++++++++++------------------ 1 file changed, 175 insertions(+), 149 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 5b9a75c045..76accc1f37 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -16,7 +16,7 @@ static std::pair get_center_and_radius(const std::vector& { Vec2ds out; double z = 0.; - for (const Vec3d pt : points) { + for (const Vec3d& pt : points) { Vec3d pt_transformed = trafo * pt; z = pt_transformed.z(); out.emplace_back(pt_transformed.x(), pt_transformed.y()); @@ -27,6 +27,14 @@ static std::pair get_center_and_radius(const std::vector& return std::make_pair(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius); } +static bool circle_fit_is_ok(const std::vector& pts, const Vec3d& center, double radius) +{ + for (const Vec3d& pt : pts) + if (std::abs((pt - center).norm() - radius) > 0.05) + return false; + return true; +} + static std::array orthonormal_basis(const Vec3d& v) { std::array ret; @@ -244,10 +252,7 @@ void MeasuringImpl::update_planes() void MeasuringImpl::extract_features() { - auto are_angles_same = [](double a, double b) { return Slic3r::is_approx(a,b); }; - auto are_lengths_same = [](double a, double b) { return Slic3r::is_approx(a,b); }; - - std::vector angles; + std::vector angles; // placed in outer scope to prevent reallocations std::vector lengths; @@ -265,175 +270,196 @@ void MeasuringImpl::extract_features() if (border.size() <= 1) continue; - // Given an idx into border, return the index that is idx+offset position, - // while taking into account the need for warp-around and the fact that - // the first and last point are the same. - auto offset_to_index = [border_size = int(border.size())](int idx, int offset) -> int { - assert(std::abs(offset) < border_size); - int out = idx+offset; - if (out >= border_size) - out = out - border_size; - else if (out < 0) - out = border_size + out; + bool done = false; - return out; - }; + if (const auto& [center, radius] = get_center_and_radius(border, trafo); + (border.size()>4) && circle_fit_is_ok(border, center, radius)) { + // The whole border is one circle. Just add it into the list of features + // and we are done. - // First calculate angles at all the vertices. - angles.clear(); - lengths.clear(); - int first_different_angle_idx = 0; - for (int i=0; i M_PI) - angle = 2*M_PI - angle; + bool is_polygon = border.size()>4 && border.size()<=8; + bool lengths_match = std::all_of(border.begin()+2, border.end(), [is_polygon](const Vec3d& pt) { + return Slic3r::is_approx((pt - *((&pt)-1)).squaredNorm(), (*((&pt)-1) - *((&pt)-2)).squaredNorm(), is_polygon ? 0.01 : 0.01); + }); - angles.push_back(angle); - lengths.push_back(v2.norm()); - if (first_different_angle_idx == 0 && angles.size() > 1) { - if (! are_angles_same(angles.back(), angles[angles.size()-2])) - first_different_angle_idx = angles.size()-1; + if (lengths_match && (is_polygon || border.size() > 8)) { + if (is_polygon) { + // This is a polygon, add the separate edges with the center. + for (int j=0; j circles; - std::vector edges; - std::vector> circles_idxs; - //std::vector circles_lengths; - std::vector single_circle; // could be in loop-scope, but reallocations - double single_circle_length = 0.; - int first_pt_idx = offset_to_index(first_different_angle_idx, 1); - int i = first_pt_idx; - while (i != first_pt_idx || first_iter) { - if (are_angles_same(angles[i], angles[offset_to_index(i,-1)]) - && i != offset_to_index(first_pt_idx, -1) // not the last point - && i != start_idx ) { - // circle - if (! circle) { - circle = true; - single_circle.clear(); - single_circle_length = 0.; - start_idx = offset_to_index(i, -2); - single_circle = { border[start_idx], border[offset_to_index(start_idx,1)] }; - single_circle_length += lengths[offset_to_index(i, -1)]; + if (! done) { + // In this case, the border is not a circle and may contain circular + // segments. Try to find them and then add all remaining edges as edges. + + auto are_angles_same = [](double a, double b) { return Slic3r::is_approx(a,b,0.01); }; + auto are_lengths_same = [](double a, double b) { return Slic3r::is_approx(a,b,0.01); }; + + + // Given an idx into border, return the index that is idx+offset position, + // while taking into account the need for wrap-around and the fact that + // the first and last point are the same. + auto offset_to_index = [border_size = int(border.size())](int idx, int offset) -> int { + assert(std::abs(offset) < border_size); + int out = idx+offset; + if (out >= border_size) + out = out - border_size; + else if (out < 0) + out = border_size + out; + + return out; + }; + + // First calculate angles at all the vertices. + angles.clear(); + lengths.clear(); + int first_different_angle_idx = 0; + for (int i=0; i M_PI) + angle = 2*M_PI - angle; + + angles.push_back(angle); + lengths.push_back(v2.norm()); + if (first_different_angle_idx == 0 && angles.size() > 1) { + if (! are_angles_same(angles.back(), angles[angles.size()-2])) + first_different_angle_idx = angles.size()-1; } - single_circle.emplace_back(border[i]); - single_circle_length += lengths[i]; - } else { - if (circle && single_circle.size() >= 5) { // Less than 5 vertices? Not a circle. + } + assert(border.size() == angles.size()); + assert(border.size() == lengths.size()); + + // First go around the border and pick what might be circular segments. + // Save pair of indices to where such potential segments start and end. + // Also remember the length of these segments. + int start_idx = -1; + bool circle = false; + bool first_iter = true; + std::vector circles; + std::vector edges; + std::vector> circles_idxs; + //std::vector circles_lengths; + std::vector single_circle; // could be in loop-scope, but reallocations + double single_circle_length = 0.; + int first_pt_idx = offset_to_index(first_different_angle_idx, 1); + int i = first_pt_idx; + while (i != first_pt_idx || first_iter) { + if (are_angles_same(angles[i], angles[offset_to_index(i,-1)]) + && i != offset_to_index(first_pt_idx, -1) // not the last point + && i != start_idx ) { + // circle + if (! circle) { + circle = true; + single_circle.clear(); + single_circle_length = 0.; + start_idx = offset_to_index(i, -2); + single_circle = { border[start_idx], border[offset_to_index(start_idx,1)] }; + single_circle_length += lengths[offset_to_index(i, -1)]; + } single_circle.emplace_back(border[i]); single_circle_length += lengths[i]; + } else { + if (circle && single_circle.size() >= 5) { // Less than 5 vertices? Not a circle. + single_circle.emplace_back(border[i]); + single_circle_length += lengths[i]; - bool accept_circle = true; - { - // Check that lengths of internal (!!!) edges match. - int j = offset_to_index(start_idx, 3); - while (j != i) { - if (! are_lengths_same(lengths[offset_to_index(j,-1)], lengths[j])) { - accept_circle = false; - break; - } - j = offset_to_index(j, 1); - } - } - - if (accept_circle) { - const auto& [center, radius] = get_center_and_radius(single_circle, trafo); - - // Check that the fit went well. The tolerance is high, only to - // reject complete failures. - for (const Vec3d& pt : single_circle) { - if (std::abs((pt - center).norm() - radius) > 0.5) { - accept_circle = false; - break; + bool accept_circle = true; + { + // Check that lengths of internal (!!!) edges match. + int j = offset_to_index(start_idx, 3); + while (j != i) { + if (! are_lengths_same(lengths[offset_to_index(j,-1)], lengths[j])) { + accept_circle = false; + break; + } + j = offset_to_index(j, 1); } } - // If the segment subtends less than 90 degrees, throw it away. - accept_circle &= single_circle_length / radius > 0.9*M_PI/2.; - - // If this is all-around and 5 to 8 vertices, consider it a polygon. - bool is_polygon = start_idx == i && single_circle.size() <= 9 && single_circle.size() >= 6; - if (accept_circle) { - // Add the circle and remember indices into borders. - circles_idxs.emplace_back(start_idx, i); - if (is_polygon) { - for (int j=0; j<=i; ++j) // No wrap-around handling needed here. - edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, - border[j==0 ? border.size()-1 : j-1], border[j], - std::make_optional(center))); - } - else + const auto& [center, radius] = get_center_and_radius(single_circle, trafo); + + // Check that the fit went well. The tolerance is high, only to + // reject complete failures. + accept_circle &= circle_fit_is_ok(single_circle, center, radius); + + // If the segment subtends less than 90 degrees, throw it away. + accept_circle &= single_circle_length / radius > 0.9*M_PI/2.; + + if (accept_circle) { + // Add the circle and remember indices into borders. + circles_idxs.emplace_back(start_idx, i); circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius)); + } } } + circle = false; } - circle = false; - } - // Take care of the wrap around. - first_iter = false; - i = offset_to_index(i, 1); - } - - // We have the circles. Now go around again and pick edges, while jumping over circles. - if (circles_idxs.empty()) { - // Just add all edges. - for (int i=1; i 1 || circles_idxs.front().first != circles_idxs.front().second) { + // There is at least one circular segment. Start at its end and add edges until the start of the next one. + int i = circles_idxs.front().second; + int circle_idx = 1; + while (true) { + i = offset_to_index(i, 1); + edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[offset_to_index(i,-1)], border[i])); + if (circle_idx < int(circles_idxs.size()) && i == circles_idxs[circle_idx].first) { + i = circles_idxs[circle_idx].second; + ++circle_idx; + } + if (i == circles_idxs.front().first) + break; } - if (i == circles_idxs.front().first) - break; } - } - // Merge adjacent edges where needed. - assert(std::all_of(edges.begin(), edges.end(), - [](const SurfaceFeature& f) { return f.get_type() == SurfaceFeatureType::Edge; })); - for (int i=edges.size()-1; i>=0; --i) { - const auto& [first_start, first_end] = edges[i==0 ? edges.size()-1 : i-1].get_edge(); - const auto& [second_start, second_end] = edges[i].get_edge(); + // Merge adjacent edges where needed. + assert(std::all_of(edges.begin(), edges.end(), + [](const SurfaceFeature& f) { return f.get_type() == SurfaceFeatureType::Edge; })); + for (int i=edges.size()-1; i>=0; --i) { + const auto& [first_start, first_end] = edges[i==0 ? edges.size()-1 : i-1].get_edge(); + const auto& [second_start, second_end] = edges[i].get_edge(); - if (Slic3r::is_approx(first_end, second_start) - && Slic3r::is_approx((first_end-first_start).normalized().dot((second_end-second_start).normalized()), 1.)) { - // The edges have the same direction and share a point. Merge them. - edges[i==0 ? edges.size()-1 : i-1] = SurfaceFeature(SurfaceFeatureType::Edge, first_start, second_end); - edges.erase(edges.begin() + i); + if (Slic3r::is_approx(first_end, second_start) + && Slic3r::is_approx((first_end-first_start).normalized().dot((second_end-second_start).normalized()), 1.)) { + // The edges have the same direction and share a point. Merge them. + edges[i==0 ? edges.size()-1 : i-1] = SurfaceFeature(SurfaceFeatureType::Edge, first_start, second_end); + edges.erase(edges.begin() + i); + } } - } - // Now move the circles and edges into the feature list for the plane. - assert(std::all_of(circles.begin(), circles.end(), [](const SurfaceFeature& f) { - return f.get_type() == SurfaceFeatureType::Circle; - })); - assert(std::all_of(edges.begin(), edges.end(), [](const SurfaceFeature& f) { - return f.get_type() == SurfaceFeatureType::Edge; - })); - plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(circles.begin()), - std::make_move_iterator(circles.end())); - plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(edges.begin()), - std::make_move_iterator(edges.end())); + // Now move the circles and edges into the feature list for the plane. + assert(std::all_of(circles.begin(), circles.end(), [](const SurfaceFeature& f) { + return f.get_type() == SurfaceFeatureType::Circle; + })); + assert(std::all_of(edges.begin(), edges.end(), [](const SurfaceFeature& f) { + return f.get_type() == SurfaceFeatureType::Edge; + })); + plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(circles.begin()), + std::make_move_iterator(circles.end())); + plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(edges.begin()), + std::make_move_iterator(edges.end())); + } } // The last surface feature is the plane itself. From e0ba6c69f4a959e6e04cc1bfe1a0d6f81f46242c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 1 Dec 2022 13:34:29 +0100 Subject: [PATCH 48/99] Fixed warnings --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 2b848bd985..a0ebc832c7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -82,17 +82,6 @@ static std::string point_on_feature_type_as_string(Measure::SurfaceFeatureType t return ret; } -static std::string center_on_feature_type_as_string(Measure::SurfaceFeatureType type) -{ - std::string ret; - switch (type) { - case Measure::SurfaceFeatureType::Edge: { ret = _u8L("Center of edge"); break; } - case Measure::SurfaceFeatureType::Circle: { ret = _u8L("Center of circle"); break; } - default: { assert(false); break; } - } - return ret; -} - static GLModel::Geometry init_plane_data(const indexed_triangle_set& its, const std::vector>& planes_triangles, int idx) { assert(0 <= idx && idx < (int)planes_triangles.size()); @@ -477,13 +466,6 @@ void GLGizmoMeasure::data_changed() m_is_editing_distance_first_frame = true; } -static bool feature_has_center(std::optional feature) -{ - return feature.has_value() ? - (feature->get_type() == Measure::SurfaceFeatureType::Circle || (feature->get_type() == Measure::SurfaceFeatureType::Edge && feature->get_extra_point().has_value())) - : false; -} - bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { if (action == SLAGizmoEventType::ShiftDown) { From 048fb10c311e2492f8275ad7261fc9d4f5bbd197 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 1 Dec 2022 14:56:33 +0100 Subject: [PATCH 49/99] Measure gizmo - Fixed missing raycaster when promoting a point as 1st selected feature --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index a0ebc832c7..21955d5ccd 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -336,7 +336,7 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) }; auto requires_sphere_raycaster_for_picking = [this](const SelectedFeatures::Item& item) { - if (m_mode == EMode::PointSelection) + if (m_mode == EMode::PointSelection || item.feature->get_type() == Measure::SurfaceFeatureType::Point) return true; else if (m_mode == EMode::FeatureSelection) { if (is_feature_with_center(*item.feature)) From e07843e6fbf450308f8bcdc375347429a25276c3 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 1 Dec 2022 16:44:21 +0100 Subject: [PATCH 50/99] Cut: Fixed visualization of the selected connectors which are conflict + Back port a Lukas's code for enable/disable current contour --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 29 +++++++++++++++++++++------- src/slic3r/GUI/MeshUtils.cpp | 8 ++++---- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 09a7deba8a..29d578fba9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -1901,14 +1901,15 @@ void GLGizmoCut3D::render_connectors() m_has_invalid_connector = true; render_color = CONNECTOR_ERR_COLOR; } - else if (!m_connectors_editing) + else // default connector color + render_color = connector.attribs.type == CutConnectorType::Dowel ? DOWEL_COLOR : PLAG_COLOR; + + if (!m_connectors_editing) render_color = CONNECTOR_ERR_COLOR; else if (size_t(m_hover_id - m_connectors_group_id) == i) - render_color = connector.attribs.type == CutConnectorType::Dowel ? HOVERED_DOWEL_COLOR : HOVERED_PLAG_COLOR; + render_color = connector.attribs.type == CutConnectorType::Dowel ? HOVERED_DOWEL_COLOR : HOVERED_PLAG_COLOR; else if (m_selected[i]) render_color = connector.attribs.type == CutConnectorType::Dowel ? SELECTED_DOWEL_COLOR : SELECTED_PLAG_COLOR; - else // neither hover nor picking - render_color = connector.attribs.type == CutConnectorType::Dowel ? DOWEL_COLOR : PLAG_COLOR; const Camera& camera = wxGetApp().plater()->get_camera(); if (connector.attribs.type == CutConnectorType::Dowel && @@ -2141,12 +2142,14 @@ bool GLGizmoCut3D::add_connector(CutConnectors& connectors, const Vec2d& mouse_p std::pair pos_and_normal; Vec3d pos_world; if (unproject_on_cut_plane(mouse_position.cast(), pos_and_normal, pos_world)) { - const Vec3d& hit = pos_and_normal.first; + // check if pos is out of enabled clipping plane + if (m_c->object_clipper() && !m_c->object_clipper()->is_projection_inside_cut(pos_world)) + return true; Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Add connector"), UndoRedo::SnapshotType::GizmoAction); unselect_all_connectors(); - connectors.emplace_back(hit, m_rotation_m, + connectors.emplace_back(pos_and_normal.first, m_rotation_m, m_connector_size * 0.5f, m_connector_depth_ratio, m_connector_size_tolerance, m_connector_depth_ratio_tolerance, CutConnectorAttributes( CutConnectorType(m_connector_type), @@ -2241,8 +2244,20 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi (action == SLAGizmoEventType::LeftDown || action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::Moving) ) return process_cut_line(action, mouse_position); - if (!m_connectors_editing) + if (!m_connectors_editing) { + if (0 && action == SLAGizmoEventType::LeftDown) { + // disable / enable current contour + std::pair pos_and_normal; + Vec3d pos_world; + if (unproject_on_cut_plane(mouse_position.cast(), pos_and_normal, pos_world)) { + // Following would inform the clipper about the mouse click, so it can + // toggle the respective contour as disabled. + m_c->object_clipper()->pass_mouse_click(pos_world); + return true; + } + } return false; + } CutConnectors& connectors = m_c->selection_info()->model_object()->cut_connectors; diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index e33d29ba16..0483d2bf0a 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -24,7 +24,7 @@ namespace GUI { void MeshClipper::set_behaviour(bool fill_cut, double contour_width) { - if (fill_cut != m_fill_cut || contour_width != m_contour_width) + if (fill_cut != m_fill_cut || is_approx(contour_width, m_contour_width)) m_result.reset(); m_fill_cut = fill_cut; m_contour_width = contour_width; @@ -97,7 +97,7 @@ void MeshClipper::render_cut() shader->set_uniform("view_model_matrix", camera.get_view_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); for (CutIsland& isl : m_result->cut_islands) { - isl.model.set_color(isl.disabled ? ColorRGBA(1.f, 0.f, 0.f, 1.f) : color); + isl.model.set_color(isl.disabled ? ColorRGBA(0.5f, 0.5f, 0.5f, 1.f) : color); isl.model.render(); } shader->stop_using(); @@ -132,7 +132,7 @@ void MeshClipper::render_contour() shader->set_uniform("view_model_matrix", camera.get_view_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); for (CutIsland& isl : m_result->cut_islands) { - isl.model_expanded.set_color(color); + isl.model_expanded.set_color(isl.disabled ? ColorRGBA(1.f, 0.f, 0.f, 1.f) : color); isl.model_expanded.render(); } shader->stop_using(); @@ -155,7 +155,7 @@ bool MeshClipper::is_projection_inside_cut(const Vec3d& point_in) const for (const CutIsland& isl : m_result->cut_islands) { if (isl.expoly_bb.contains(pt_2d) && isl.expoly.contains(pt_2d)) - return true; + return !isl.disabled; } return false; } From 8aa62b88f641b1e5b1ede0930f4ce298f654ab7e Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 2 Dec 2022 07:42:02 +0100 Subject: [PATCH 51/99] Measurement: Fixed edge detection on single-triangle planes --- src/libslic3r/Measure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 76accc1f37..919c55503e 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -225,7 +225,7 @@ void MeasuringImpl::update_planes() // In case of broken meshes, this loop might be infinite. Break // out in case it is clearly going bad. - if (last_border.size() > 3*facets.size()) + if (last_border.size() > 3*facets.size()+1) goto PLANE_FAILURE; } while (he != he_start); From 9964c47fbdd86a584a2c15998b73e9740f1abe07 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 2 Dec 2022 07:56:11 +0100 Subject: [PATCH 52/99] Follow-up of 85195ac79fb2b7016b05ffff5eb33a483a4d06c2 - Fixed synch of selected features in imgui dialog --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 21955d5ccd..a2d2518d6a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -82,6 +82,17 @@ static std::string point_on_feature_type_as_string(Measure::SurfaceFeatureType t return ret; } +static std::string center_on_feature_type_as_string(Measure::SurfaceFeatureType type) +{ + std::string ret; + switch (type) { + case Measure::SurfaceFeatureType::Edge: { ret = _u8L("Center of edge"); break; } + case Measure::SurfaceFeatureType::Circle: { ret = _u8L("Center of circle"); break; } + default: { assert(false); break; } + } + return ret; +} + static GLModel::Geometry init_plane_data(const indexed_triangle_set& its, const std::vector>& planes_triangles, int idx) { assert(0 <= idx && idx < (int)planes_triangles.size()); @@ -1973,7 +1984,8 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit if (!item.feature.has_value()) return _u8L("None"); - std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id); + std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) : + item.is_center ? center_on_feature_type_as_string(item.source->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id); if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) { auto [center, radius, normal] = item.feature->get_circle(); const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); From 33949734e330f9a2942d805d5c2c7c951faf0cb9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 2 Dec 2022 09:11:50 +0100 Subject: [PATCH 53/99] Latest techs definition retargeted to 2.6 --- src/libslic3r/Technologies.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c80689f48b..f707b0f21d 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -37,12 +37,12 @@ //==================== -// 2.5.0.alpha1 techs +// 2.6.0.alpha1 techs //==================== -#define ENABLE_2_5_0_ALPHA1 1 +#define ENABLE_2_6_0_ALPHA1 1 // Enable removal of legacy OpenGL calls -#define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) +#define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_6_0_ALPHA1) // Enable OpenGL ES #define ENABLE_OPENGL_ES (0 && ENABLE_LEGACY_OPENGL_REMOVAL) // Enable OpenGL core profile context (tested against Mesa 20.1.8 on Windows) @@ -52,15 +52,15 @@ // Shows an imgui dialog with GLModel statistics data #define ENABLE_GLMODEL_STATISTICS (0 && ENABLE_LEGACY_OPENGL_REMOVAL) // Enable rework of Reload from disk command -#define ENABLE_RELOAD_FROM_DISK_REWORK (1 && ENABLE_2_5_0_ALPHA1) +#define ENABLE_RELOAD_FROM_DISK_REWORK (1 && ENABLE_2_6_0_ALPHA1) // Enable editing volumes transformation in world coordinates and instances in local coordinates -#define ENABLE_WORLD_COORDINATE (1 && ENABLE_2_5_0_ALPHA1) +#define ENABLE_WORLD_COORDINATE (1 && ENABLE_2_6_0_ALPHA1) // Enable alternative version of file_wildcards() -#define ENABLE_ALTERNATIVE_FILE_WILDCARDS_GENERATOR (1 && ENABLE_2_5_0_ALPHA1) +#define ENABLE_ALTERNATIVE_FILE_WILDCARDS_GENERATOR (1 && ENABLE_2_6_0_ALPHA1) // Enable processing of gcode G2 and G3 lines -#define ENABLE_PROCESS_G2_G3_LINES (1 && ENABLE_2_5_0_ALPHA1) +#define ENABLE_PROCESS_G2_G3_LINES (1 && ENABLE_2_6_0_ALPHA1) // Enable fix of used filament data exported to gcode file -#define ENABLE_USED_FILAMENT_POST_PROCESS (1 && ENABLE_2_5_0_ALPHA1) +#define ENABLE_USED_FILAMENT_POST_PROCESS (1 && ENABLE_2_6_0_ALPHA1) // Enable picking using raytracing #define ENABLE_RAYCAST_PICKING (1 && ENABLE_LEGACY_OPENGL_REMOVAL) #define ENABLE_RAYCAST_PICKING_DEBUG (0 && ENABLE_RAYCAST_PICKING) From fc2f0bad6e3e9ba08c65aacd52396cf6136e1df4 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 15 Nov 2022 12:17:18 +0100 Subject: [PATCH 54/99] Gizmo measure modified to accept single full instance selection, to combine the volumes meshes into a single mesh and pass it to the back end after transform it in world coordinates Changes embedded into tech ENABLE_GIZMO_MEASURE_WORLD_COORDINATES Fixed conflicts during rebase to master --- src/libslic3r/Measure.cpp | 37 ++++ src/libslic3r/Measure.hpp | 19 +- src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 230 ++++++++++++++++++++++- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 35 ++++ src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 13 ++ src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 7 + src/slic3r/GUI/Selection.cpp | 13 ++ src/slic3r/GUI/Selection.hpp | 4 + 9 files changed, 347 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index badb3b2c5f..9b930df9aa 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -47,6 +47,9 @@ public: std::optional get_feature(size_t face_idx, const Vec3d& point) const; std::vector> get_planes_triangle_indices() const; const std::vector& get_plane_features(unsigned int plane_id) const; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const TriangleMesh& get_mesh() const; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES private: void update_planes(); @@ -54,7 +57,11 @@ private: std::vector m_planes; std::vector m_face_to_plane; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + TriangleMesh m_mesh; +#else const indexed_triangle_set& m_its; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; @@ -63,7 +70,11 @@ private: MeasuringImpl::MeasuringImpl(const indexed_triangle_set& its) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +: m_mesh(its) +#else : m_its{its} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES { update_planes(); extract_features(); @@ -76,10 +87,17 @@ void MeasuringImpl::update_planes() // Now we'll go through all the facets and append Points of facets sharing the same normal. // This part is still performed in mesh coordinate system. +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const size_t num_of_facets = m_mesh.its.indices.size(); + m_face_to_plane.resize(num_of_facets, size_t(-1)); + const std::vector face_normals = its_face_normals(m_mesh.its); + const std::vector face_neighbors = its_face_neighbors(m_mesh.its); +#else const size_t num_of_facets = m_its.indices.size(); m_face_to_plane.resize(num_of_facets, size_t(-1)); const std::vector face_normals = its_face_normals(m_its); const std::vector face_neighbors = its_face_neighbors(m_its); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::vector facet_queue(num_of_facets, 0); int facet_queue_cnt = 0; const stl_normal* normal_ptr = nullptr; @@ -128,7 +146,11 @@ void MeasuringImpl::update_planes() assert(std::none_of(m_face_to_plane.begin(), m_face_to_plane.end(), [](size_t val) { return val == size_t(-1); })); // Now we will walk around each of the planes and save vertices which form the border. +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + SurfaceMesh sm(m_mesh.its); +#else SurfaceMesh sm(m_its); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES for (int plane_id=0; plane_id < int(m_planes.size()); ++plane_id) { const auto& facets = m_planes[plane_id].facets; m_planes[plane_id].borders.clear(); @@ -510,6 +532,12 @@ const std::vector& MeasuringImpl::get_plane_features(unsigned in return m_planes[plane_id].surface_features; } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +const TriangleMesh& MeasuringImpl::get_mesh() const +{ + return this->m_mesh; +} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES @@ -551,6 +579,13 @@ const std::vector& Measuring::get_plane_features(unsigned int pl return priv->get_plane_features(plane_id); } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +const TriangleMesh& Measuring::get_mesh() const +{ + return priv->get_mesh(); +} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const AngleAndEdges AngleAndEdges::Dummy = { 0.0, Vec3d::Zero(), { Vec3d::Zero(), Vec3d::Zero() }, { Vec3d::Zero(), Vec3d::Zero() }, 0.0, true }; static AngleAndEdges angle_edge_edge(const std::pair& e1, const std::pair& e2) @@ -1149,6 +1184,7 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& return result; } +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void DistAndPoints::transform(const Transform3d& trafo) { from = trafo * from; to = trafo * to; @@ -1169,6 +1205,7 @@ void AngleAndEdges::transform(const Transform3d& trafo) { const double average_scale = 0.5 * (new_e1.norm() / old_e1.norm() + new_e2.norm() / old_e2.norm()); radius = average_scale * radius; } +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index ede8c634ee..b2e2008d15 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -87,9 +87,11 @@ class MeasuringImpl; class Measuring { public: - // Construct the measurement object on a given its. The its must remain - // valid and unchanged during the whole lifetime of the object. - explicit Measuring(const indexed_triangle_set& its); + // Construct the measurement object on a given its. +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + // The its must remain valid and unchanged during the whole lifetime of the object. +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + explicit Measuring(const indexed_triangle_set& its); ~Measuring(); // Return a reference to a list of all features identified on the its. @@ -108,6 +110,11 @@ public: // Returns the surface features of the plane with the given index const std::vector& get_plane_features(unsigned int plane_id) const; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + // Returns the mesh used for measuring + const TriangleMesh& get_mesh() const; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + private: std::unique_ptr priv; }; @@ -119,7 +126,9 @@ struct DistAndPoints { Vec3d from; Vec3d to; +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void transform(const Transform3d& trafo); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; struct AngleAndEdges { @@ -132,7 +141,9 @@ struct AngleAndEdges { double radius; bool coplanar; +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void transform(const Transform3d& trafo); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES static const AngleAndEdges Dummy; }; @@ -151,6 +162,7 @@ struct MeasurementResult { return angle.has_value() || distance_infinite.has_value() || distance_strict.has_value() || distance_xyz.has_value(); } +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void transform(const Transform3d& trafo) { if (angle.has_value()) angle->transform(trafo); @@ -161,6 +173,7 @@ struct MeasurementResult { distance_xyz = (distance_strict->to - distance_strict->from).cwiseAbs(); } } +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; // Returns distance/angle between two SurfaceFeatures. diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index f707b0f21d..759871c60d 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -64,6 +64,8 @@ // Enable picking using raytracing #define ENABLE_RAYCAST_PICKING (1 && ENABLE_LEGACY_OPENGL_REMOVAL) #define ENABLE_RAYCAST_PICKING_DEBUG (0 && ENABLE_RAYCAST_PICKING) +// Enable gizmo measure combining volumes meshes and passing them to the backend in world coordinates +#define ENABLE_GIZMO_MEASURE_WORLD_COORDINATES (1 && ENABLE_2_5_0_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index a026ae2552..5ae906eac9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -5,9 +5,11 @@ #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/GUI_ObjectManipulation.hpp" -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" #include "libslic3r/Model.hpp" +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES #include "libslic3r/PresetBundle.hpp" #include "libslic3r/MeasureUtils.hpp" @@ -242,7 +244,10 @@ private: TransformHelper::Cache TransformHelper::s_cache = { { 0, 0, 0, 0 }, Matrix4d::Identity(), Transform3d::Identity() }; GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) - : GLGizmoBase(parent, icon_filename, sprite_id) +: GLGizmoBase(parent, icon_filename, sprite_id) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +, m_raycaster(nullptr) +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES { GLModel::Geometry sphere_geometry = smooth_sphere(16, 7.5f); m_sphere.mesh_raycaster = std::make_unique(std::make_shared(sphere_geometry.get_as_indexed_triangle_set())); @@ -370,8 +375,10 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) { m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // transform to world coordinates m_measurement_result.transform(m_volume_matrix); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } m_imgui->set_requires_extra_frame(); @@ -419,6 +426,9 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) void GLGizmoMeasure::data_changed() { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + update_if_needed(); +#else const Selection& selection = m_parent.get_selection(); const ModelObject* model_object = nullptr; const ModelVolume* model_volume = nullptr; @@ -429,13 +439,16 @@ void GLGizmoMeasure::data_changed() } if (model_object != m_old_model_object || model_volume != m_old_model_volume) update_if_needed(); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_last_inv_zoom = 0.0f; m_last_plane_idx = -1; if (m_pending_scale) { m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // transform to world coordinates m_measurement_result.transform(m_volume_matrix); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_pending_scale = false; } else @@ -512,6 +525,9 @@ void GLGizmoMeasure::on_set_state() m_editing_distance = false; m_is_editing_distance_first_frame = true; m_measuring.reset(); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + m_raycaster.release(); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } else { m_mode = EMode::FeatureSelection; @@ -528,10 +544,12 @@ void GLGizmoMeasure::on_set_state() } } +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES CommonGizmosDataID GLGizmoMeasure::on_get_requirements() const { return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo) | int(CommonGizmosDataID::Raycaster)); } +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::string GLGizmoMeasure::on_get_name() const { @@ -543,9 +561,15 @@ bool GLGizmoMeasure::on_is_activable() const const Selection& selection = m_parent.get_selection(); bool res = (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) ? selection.is_single_full_instance() : +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier(); + if (res) + res &= !selection.contains_sinking_volumes(); +#else selection.is_single_volume() || selection.is_single_volume_instance(); if (res) res &= !selection.get_first_volume()->is_sinking(); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES return res; } @@ -562,8 +586,10 @@ void GLGizmoMeasure::on_render() const Selection& selection = m_parent.get_selection(); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA && selection.is_single_full_instance()) || (selection.is_single_volume() || selection.is_single_volume_instance())) { +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES update_if_needed(); const Camera& camera = wxGetApp().plater()->get_camera(); @@ -572,7 +598,11 @@ void GLGizmoMeasure::on_render() Vec3f position_on_model; Vec3f normal_on_model; size_t model_facet_idx; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const bool mouse_on_object = m_raycaster.raycaster()->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); +#else const bool mouse_on_object = m_c->raycaster()->raycasters().front()->unproject_on_mesh(m_mouse_pos, m_volume_matrix, camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const bool is_hovering_on_feature = (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) && m_hover_id != -1; auto update_circle = [this, inv_zoom]() { @@ -581,7 +611,11 @@ void GLGizmoMeasure::on_render() m_last_circle = m_curr_feature; m_circle.reset(); const auto [center, radius, normal] = m_curr_feature->get_circle(); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); +#else GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), m_volume_matrix.cast()); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_circle.mesh_raycaster = std::make_unique(std::make_shared(circle_geometry.get_as_indexed_triangle_set())); m_circle.model.init_from(std::move(circle_geometry)); return true; @@ -639,7 +673,11 @@ void GLGizmoMeasure::on_render() const auto [idx, normal, point] = m_curr_feature->get_plane(); if (m_last_plane_idx != idx) { m_last_plane_idx = idx; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const indexed_triangle_set& its = m_measuring->get_mesh().its; +#else const indexed_triangle_set its = (m_old_model_volume != nullptr) ? m_old_model_volume->mesh().its : m_old_model_object->volumes.front()->mesh().its; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const std::vector> planes_triangles = m_measuring->get_planes_triangle_indices(); GLModel::Geometry init_data = init_plane_data(its, planes_triangles, idx); m_plane.reset(); @@ -689,12 +727,20 @@ void GLGizmoMeasure::on_render() if (extra.has_value() && m_hover_id == POINT_ID) m_curr_point_on_feature_position = *extra; else +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + m_curr_point_on_feature_position = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); +#else m_curr_point_on_feature_position = m_volume_matrix.inverse() * position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES break; } case Measure::SurfaceFeatureType::Plane: { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + m_curr_point_on_feature_position = position_on_feature(PLANE_ID, camera); +#else m_curr_point_on_feature_position = m_volume_matrix.inverse() * position_on_feature(PLANE_ID, camera); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES break; } case Measure::SurfaceFeatureType::Circle: @@ -704,9 +750,17 @@ void GLGizmoMeasure::on_render() m_curr_point_on_feature_position = center; else { const Vec3d world_pof = position_on_feature(CIRCLE_ID, camera, [](const Vec3f& v) { return v; }); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Eigen::Hyperplane plane(normal, center); +#else const Eigen::Hyperplane plane(m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal, m_volume_matrix * center); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Transform3d local_to_model_matrix = Geometry::translation_transform(center) * Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), normal); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Vec3d local_proj = local_to_model_matrix.inverse() * plane.projection(world_pof); +#else const Vec3d local_proj = local_to_model_matrix.inverse() * m_volume_matrix.inverse() * plane.projection(world_pof); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES double angle = std::atan2(local_proj.y(), local_proj.x()); if (angle < 0.0) angle += 2.0 * double(M_PI); @@ -767,8 +821,12 @@ void GLGizmoMeasure::on_render() default: { assert(false); break; } case Measure::SurfaceFeatureType::Point: { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d feature_matrix = Geometry::translation_transform(feature.get_point()) * Geometry::scale_transform(inv_zoom); +#else const Vec3d position = TransformHelper::model_to_world(feature.get_point(), m_volume_matrix); const Transform3d feature_matrix = Geometry::translation_transform(position) * Geometry::scale_transform(inv_zoom); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(feature_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); @@ -785,8 +843,12 @@ void GLGizmoMeasure::on_render() const auto& [center, radius, normal] = feature.get_circle(); // render center if (update_raycasters_transform) { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d center_matrix = Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom); +#else const Vec3d center_world = TransformHelper::model_to_world(center, m_volume_matrix); const Transform3d center_matrix = Geometry::translation_transform(center_world) * Geometry::scale_transform(inv_zoom); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(center_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); @@ -809,7 +871,11 @@ void GLGizmoMeasure::on_render() } else { GLModel circle; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); +#else GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), m_volume_matrix.cast()); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES circle.init_from(std::move(circle_geometry)); set_emission_uniform(colors.back(), hover); circle.set_color(colors.back()); @@ -825,8 +891,12 @@ void GLGizmoMeasure::on_render() if (update_raycasters_transform) { const std::optional extra = feature.get_extra_point(); if (extra.has_value()) { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d point_matrix = Geometry::translation_transform(*extra) * Geometry::scale_transform(inv_zoom); +#else const Vec3d extra_world = TransformHelper::model_to_world(*extra, m_volume_matrix); const Transform3d point_matrix = Geometry::translation_transform(extra_world) * Geometry::scale_transform(inv_zoom); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(point_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); @@ -838,11 +908,17 @@ void GLGizmoMeasure::on_render() } // render edge if (m_mode != EMode::CenterSelection) { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d edge_matrix = Geometry::translation_transform(from) * + Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * + Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); +#else const Vec3d from_world = TransformHelper::model_to_world(from, m_volume_matrix); const Vec3d to_world = TransformHelper::model_to_world(to, m_volume_matrix); const Transform3d edge_matrix = Geometry::translation_transform(from_world) * Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to_world - from_world) * Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to_world - from_world).norm() }); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(edge_matrix); set_emission_uniform(colors.back(), hover); m_cylinder.model.set_color(colors.back()); @@ -857,16 +933,27 @@ void GLGizmoMeasure::on_render() } case Measure::SurfaceFeatureType::Plane: { - const auto& [idx, normal, pt] = feature.get_plane(); - assert(idx < m_plane_models_cache.size()); - set_matrix_uniforms(m_volume_matrix); - set_emission_uniform(colors.front(), hover); - m_plane_models_cache[idx].set_color(colors.front()); - m_plane_models_cache[idx].render(); + // no need to render the plane in case it is rendered with the same color as the volume in the 3D scene + if (colors.front() != m_parent.get_selection().get_first_volume()->render_color) { + const auto& [idx, normal, pt] = feature.get_plane(); + assert(idx < m_plane_models_cache.size()); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + set_matrix_uniforms(Transform3d::Identity()); +#else + set_matrix_uniforms(m_volume_matrix); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + set_emission_uniform(colors.front(), hover); + m_plane_models_cache[idx].set_color(colors.front()); + m_plane_models_cache[idx].render(); + } if (update_raycasters_transform) { auto it = m_raycasters.find(PLANE_ID); if (it != m_raycasters.end() && it->second != nullptr) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + it->second->set_transform(Transform3d::Identity()); +#else it->second->set_transform(m_volume_matrix); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } break; } @@ -921,7 +1008,11 @@ void GLGizmoMeasure::on_render() auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_1_ID; }); if (it != m_selection_raycasters.end()) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + (*it)->set_transform(Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); +#else (*it)->set_transform(m_volume_matrix * Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } } if (m_selected_features.second.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.second.feature)) { @@ -931,14 +1022,22 @@ void GLGizmoMeasure::on_render() auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); if (it != m_selection_raycasters.end()) +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + (*it)->set_transform(Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); +#else (*it)->set_transform(m_volume_matrix * Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } } if (is_hovering_on_feature && m_curr_point_on_feature_position.has_value()) { if (m_hover_id != POINT_ID) { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Transform3d matrix = Geometry::translation_transform(*m_curr_point_on_feature_position) * Geometry::scale_transform(inv_zoom); +#else const Vec3d position = TransformHelper::model_to_world(*m_curr_point_on_feature_position, m_volume_matrix); const Transform3d matrix = Geometry::translation_transform(position) * Geometry::scale_transform(inv_zoom); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set_matrix_uniforms(matrix); const ColorRGBA color = hover_selection_color(); set_emission_uniform(color, true); @@ -951,7 +1050,9 @@ void GLGizmoMeasure::on_render() if (old_cullface) glsafe(::glEnable(GL_CULL_FACE)); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES render_dimensioning(); } @@ -968,6 +1069,24 @@ void GLGizmoMeasure::update_if_needed() } }; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + auto do_update = [this, update_plane_models_cache](const std::vector& volumes_cache, const Selection& selection) { + TriangleMesh composite_mesh; + for (const auto& vol : volumes_cache) { +// if (selection.is_single_full_instance() && vol.volume->is_modifier()) +// continue; + + TriangleMesh volume_mesh = vol.volume->mesh(); + volume_mesh.transform(vol.instance->get_transformation().get_matrix() * vol.volume->get_transformation().get_matrix()); + composite_mesh.merge(volume_mesh); + } + + m_measuring.reset(new Measure::Measuring(composite_mesh.its)); + update_plane_models_cache(m_measuring->get_mesh().its); + m_raycaster.update_from(m_measuring->get_mesh()); + m_volumes_cache = volumes_cache; + }; +#else auto do_update = [this, update_plane_models_cache](const ModelObject* object, const ModelVolume* volume) { const indexed_triangle_set& its = (volume != nullptr) ? volume->mesh().its : object->volumes.front()->mesh().its; m_measuring.reset(new Measure::Measuring(its)); @@ -977,24 +1096,44 @@ void GLGizmoMeasure::update_if_needed() // Let's save what we calculated it from: m_volumes_matrices.clear(); m_volumes_types.clear(); - m_first_instance_scale = Vec3d::Ones(); + m_first_instance_scale = Vec3d::Ones(); m_first_instance_mirror = Vec3d::Ones(); if (object != nullptr) { for (const ModelVolume* vol : object->volumes) { m_volumes_matrices.push_back(vol->get_matrix()); m_volumes_types.push_back(vol->type()); } - m_first_instance_scale = object->instances.front()->get_scaling_factor(); + m_first_instance_scale = object->instances.front()->get_scaling_factor(); m_first_instance_mirror = object->instances.front()->get_mirror(); } m_old_model_object = object; m_old_model_volume = volume; }; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Selection& selection = m_parent.get_selection(); if (selection.is_empty()) return; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Selection::IndicesList& idxs = selection.get_volume_idxs(); + std::vector volumes_cache; + volumes_cache.reserve(idxs.size()); + for (unsigned int idx : idxs) { + const GLVolume* v = selection.get_volume(idx); + const ModelObject* obj = selection.get_model()->objects[v->object_idx()]; + const ModelInstance* inst = obj->instances[v->instance_idx()]; + const ModelVolume* vol = obj->volumes[v->volume_idx()]; + const VolumeCacheItem item = { obj, inst, vol, inst->get_matrix() * vol->get_matrix() }; + volumes_cache.emplace_back(item); + } + + if (m_state != On || volumes_cache.empty()) + return; + + if (m_measuring == nullptr || m_volumes_cache != volumes_cache) + do_update(volumes_cache, selection); +#else m_volume_matrix = selection.get_first_volume()->world_matrix(); const ModelObject* mo = m_c->selection_info()->model_object(); @@ -1023,6 +1162,7 @@ void GLGizmoMeasure::update_if_needed() break; } } +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } void GLGizmoMeasure::disable_scene_raycasters() @@ -1142,6 +1282,62 @@ void GLGizmoMeasure::render_dimensioning() const double ratio = new_value / old_value; wxGetApp().plater()->take_snapshot(_L("Scale")); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + struct TrafoData + { + double ratio; + Vec3d old_pivot; + Vec3d new_pivot; + Transform3d scale_matrix; + + TrafoData(double ratio, const Vec3d& pivot) { + this->ratio = ratio; + this->scale_matrix = Geometry::scale_transform(ratio); + this->old_pivot = pivot; + this->new_pivot = { pivot.x(), pivot.y(), (this->scale_matrix * pivot).z() }; + } + + Vec3d transform(const Vec3d& point) const { + return this->scale_matrix * (point - this->old_pivot) + this->new_pivot; + } + }; + + auto scale_feature = [this](Measure::SurfaceFeature& feature, const TrafoData& trafo_data) { + switch (feature.get_type()) + { + case Measure::SurfaceFeatureType::Point: + { + feature = Measure::SurfaceFeature(trafo_data.transform(feature.get_point())); + break; + } + case Measure::SurfaceFeatureType::Edge: + { + const auto [from, to] = feature.get_edge(); + const std::optional extra = feature.get_extra_point(); + const std::optional new_extra = extra.has_value() ? trafo_data.transform(*extra) : extra; + feature = Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, trafo_data.transform(from), trafo_data.transform(to), new_extra); + break; + } + case Measure::SurfaceFeatureType::Circle: + { + const auto [center, radius, normal] = feature.get_circle(); + feature = Measure::SurfaceFeature(Measure::SurfaceFeatureType::Circle, trafo_data.transform(center), normal, std::nullopt, trafo_data.ratio * radius); + break; + } + case Measure::SurfaceFeatureType::Plane: + { + const auto [idx, normal, origin] = feature.get_plane(); + feature = Measure::SurfaceFeature(Measure::SurfaceFeatureType::Plane, normal, trafo_data.transform(origin), std::nullopt, idx); + break; + } + } + }; + + const TrafoData trafo_data(ratio, m_parent.get_selection().get_bounding_box().center()); + scale_feature(*m_selected_features.first.feature, trafo_data); + scale_feature(*m_selected_features.second.feature, trafo_data); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + TransformationType type; type.set_world(); type.set_relative(); @@ -1200,8 +1396,10 @@ void GLGizmoMeasure::render_dimensioning() assert(f1.get_type() == Measure::SurfaceFeatureType::Point && f2.get_type() == Measure::SurfaceFeatureType::Edge); std::pair e = f2.get_edge(); // Transform to world coordinates +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES e.first = TransformHelper::model_to_world(e.first, m_volume_matrix); e.second = TransformHelper::model_to_world(e.second, m_volume_matrix); +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Vec3d v_proj = m_measurement_result.distance_infinite->to; @@ -1482,15 +1680,21 @@ void GLGizmoMeasure::render_debug_dialog() { case Measure::SurfaceFeatureType::Point: { +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(item.feature->get_point()), ImGui::GetStyleColorVec4(ImGuiCol_Text)); +#else const Vec3d position = m_volume_matrix * item.feature->get_point(); add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(position), ImGui::GetStyleColorVec4(ImGuiCol_Text)); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES break; } case Measure::SurfaceFeatureType::Edge: { auto [from, to] = item.feature->get_edge(); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES from = m_volume_matrix * from; to = m_volume_matrix * to; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(from), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(to), ImGui::GetStyleColorVec4(ImGuiCol_Text)); break; @@ -1498,8 +1702,10 @@ void GLGizmoMeasure::render_debug_dialog() case Measure::SurfaceFeatureType::Plane: { auto [idx, normal, origin] = item.feature->get_plane(); +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES origin = m_volume_matrix * origin; normal = m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(origin), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_value", ImGuiWrapper::COL_ORANGE_LIGHT, format_double(idx), ImGui::GetStyleColorVec4(ImGuiCol_Text)); @@ -1508,9 +1714,13 @@ void GLGizmoMeasure::render_debug_dialog() case Measure::SurfaceFeatureType::Circle: { auto [center, radius, normal] = item.feature->get_circle(); +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); +#else const Vec3d on_circle = m_volume_matrix * (center + radius * Measure::get_orthogonal(normal, true)); center = m_volume_matrix * center; normal = (m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal).normalized(); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES radius = (on_circle - center).norm(); add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(center), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 7bfc2e8c93..606012f7c4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -5,10 +5,16 @@ #include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GUI_Utils.hpp" #include "libslic3r/Measure.hpp" +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" +#include "libslic3r/Model.hpp" +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES namespace Slic3r { +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES class ModelVolume; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES enum class ModelVolumeType : int; @@ -68,6 +74,23 @@ class GLGizmoMeasure : public GLGizmoBase } }; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + struct VolumeCacheItem + { + const ModelObject* object{ nullptr }; + const ModelInstance* instance{ nullptr }; + const ModelVolume* volume{ nullptr }; + Transform3d world_trafo; + + bool operator == (const VolumeCacheItem& other) const { + return this->object == other.object && this->instance == other.instance && this->volume == other.volume && + this->world_trafo.isApprox(other.world_trafo); + } + }; + + std::vector m_volumes_cache; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + EMode m_mode{ EMode::FeatureSelection }; Measure::MeasurementResult m_measurement_result; @@ -85,7 +108,13 @@ class GLGizmoMeasure : public GLGizmoBase }; Dimensioning m_dimensioning; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + // Uses a standalone raycaster and not the shared one because of the + // difference in how the mesh is updated + CommonGizmosDataObjects::Raycaster m_raycaster; +#else Transform3d m_volume_matrix{ Transform3d::Identity() }; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::vector m_plane_models_cache; std::map> m_raycasters; std::vector> m_selection_raycasters; @@ -100,17 +129,21 @@ class GLGizmoMeasure : public GLGizmoBase std::vector m_scene_raycasters; // These hold information to decide whether recalculation is necessary: +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::vector m_volumes_matrices; std::vector m_volumes_types; Vec3d m_first_instance_scale{ Vec3d::Ones() }; Vec3d m_first_instance_mirror{ Vec3d::Ones() }; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES float m_last_inv_zoom{ 0.0f }; std::optional m_last_circle; int m_last_plane_idx{ -1 }; bool m_mouse_left_down{ false }; // for detection left_up of this gizmo +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const ModelObject* m_old_model_object{ nullptr }; const ModelVolume* m_old_model_volume{ nullptr }; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES Vec2d m_mouse_pos{ Vec2d::Zero() }; @@ -153,7 +186,9 @@ protected: bool on_is_activable() const override; void on_render() override; void on_set_state() override; +#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES CommonGizmosDataID on_get_requirements() const override; +#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES virtual void on_render_input_window(float x, float y, float bottom_limit) override; virtual void on_register_raycasters_for_picking() override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 394e879b7c..dca64a5266 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -327,6 +327,19 @@ const TriangleMesh* HollowedMesh::get_hollowed_interior() const } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +void Raycaster::update_from(const TriangleMesh& mesh) +{ + std::vector meshes = { &mesh }; + if (meshes != m_old_meshes) { + wxBusyCursor wait; + m_raycasters.clear(); + m_raycasters.emplace_back(new MeshRaycaster(std::make_shared(mesh))); + m_old_meshes = meshes; + } + validate(); +} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES void Raycaster::on_update() diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 42faa25f84..b02e3a920c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -137,6 +137,9 @@ protected: virtual void on_update() = 0; CommonGizmosDataPool* get_pool() const { return m_common; } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + void validate() { m_is_valid = true; } +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES private: bool m_is_valid = false; @@ -242,6 +245,10 @@ public: const MeshRaycaster* raycaster() const { assert(m_raycasters.size() == 1); return m_raycasters.front().get(); } std::vector raycasters() const; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + void update_from(const TriangleMesh& mesh); +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + protected: void on_update() override; void on_release() override; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index b27f7a7381..0e893fb16c 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -613,6 +613,19 @@ bool Selection::contains_any_volume(const std::vector& volume_idxs return false; } +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +bool Selection::contains_sinking_volumes(bool ignore_modifiers) const +{ + for (const GLVolume* v : *m_volumes) { + if (!ignore_modifiers || !v->is_modifier) { + if (v->is_sinking()) + return true; + } + } + return false; +} +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + bool Selection::matches(const std::vector& volume_idxs) const { unsigned int count = 0; diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 34b88f1606..cf9d26fc7d 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -338,6 +338,10 @@ public: bool contains_all_volumes(const std::vector& volume_idxs) const; // returns true if the selection contains at least one of the given indices bool contains_any_volume(const std::vector& volume_idxs) const; +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + // returns true if the selection contains any sinking volume + bool contains_sinking_volumes(bool ignore_modifiers = true) const; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // returns true if the selection contains all and only the given indices bool matches(const std::vector& volume_idxs) const; From 4606d8266a87e92c75701adfb4ece322534555d6 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 15 Nov 2022 12:42:22 +0100 Subject: [PATCH 55/99] Added missing declaration --- src/libslic3r/Measure.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index b2e2008d15..9cc380dd2b 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -12,6 +12,11 @@ struct indexed_triangle_set; namespace Slic3r { + +#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES +class TriangleMesh; +#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + namespace Measure { From 268365b92db90084f9b142c7bd46ebf3b708ec1d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 15 Nov 2022 16:07:38 +0100 Subject: [PATCH 56/99] Measurement: refactoring - do not touch common raycaster interface when there is no need --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 9 +++------ src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 15 --------------- src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 8 -------- 4 files changed, 5 insertions(+), 31 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 5ae906eac9..8cfbf634eb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -245,9 +245,6 @@ TransformHelper::Cache TransformHelper::s_cache = { { 0, 0, 0, 0 }, Matrix4d::Id GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -, m_raycaster(nullptr) -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES { GLModel::Geometry sphere_geometry = smooth_sphere(16, 7.5f); m_sphere.mesh_raycaster = std::make_unique(std::make_shared(sphere_geometry.get_as_indexed_triangle_set())); @@ -526,7 +523,7 @@ void GLGizmoMeasure::on_set_state() m_is_editing_distance_first_frame = true; m_measuring.reset(); #if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - m_raycaster.release(); + m_raycaster.reset(); #endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } else { @@ -599,7 +596,7 @@ void GLGizmoMeasure::on_render() Vec3f normal_on_model; size_t model_facet_idx; #if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const bool mouse_on_object = m_raycaster.raycaster()->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); + const bool mouse_on_object = m_raycaster->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); #else const bool mouse_on_object = m_c->raycaster()->raycasters().front()->unproject_on_mesh(m_mouse_pos, m_volume_matrix, camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); #endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES @@ -1083,7 +1080,7 @@ void GLGizmoMeasure::update_if_needed() m_measuring.reset(new Measure::Measuring(composite_mesh.its)); update_plane_models_cache(m_measuring->get_mesh().its); - m_raycaster.update_from(m_measuring->get_mesh()); + m_raycaster.reset(new MeshRaycaster(std::make_shared(m_measuring->get_mesh()))); m_volumes_cache = volumes_cache; }; #else diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 606012f7c4..fbbf30da78 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -4,9 +4,9 @@ #include "GLGizmoBase.hpp" #include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GUI_Utils.hpp" +#include "slic3r/GUI/MeshUtils.hpp" #include "libslic3r/Measure.hpp" #if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" #include "libslic3r/Model.hpp" #endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES @@ -111,7 +111,7 @@ class GLGizmoMeasure : public GLGizmoBase #if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // Uses a standalone raycaster and not the shared one because of the // difference in how the mesh is updated - CommonGizmosDataObjects::Raycaster m_raycaster; + std::unique_ptr m_raycaster; #else Transform3d m_volume_matrix{ Transform3d::Identity() }; #endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index dca64a5266..11c44113bc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -327,21 +327,6 @@ const TriangleMesh* HollowedMesh::get_hollowed_interior() const } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -void Raycaster::update_from(const TriangleMesh& mesh) -{ - std::vector meshes = { &mesh }; - if (meshes != m_old_meshes) { - wxBusyCursor wait; - m_raycasters.clear(); - m_raycasters.emplace_back(new MeshRaycaster(std::make_shared(mesh))); - m_old_meshes = meshes; - } - validate(); -} -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - - void Raycaster::on_update() { wxBusyCursor wait; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index b02e3a920c..3878c6b25a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -137,10 +137,6 @@ protected: virtual void on_update() = 0; CommonGizmosDataPool* get_pool() const { return m_common; } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void validate() { m_is_valid = true; } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - private: bool m_is_valid = false; CommonGizmosDataPool* m_common = nullptr; @@ -245,10 +241,6 @@ public: const MeshRaycaster* raycaster() const { assert(m_raycasters.size() == 1); return m_raycasters.front().get(); } std::vector raycasters() const; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void update_from(const TriangleMesh& mesh); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - protected: void on_update() override; void on_release() override; From 5382f4077ac88c988647979c4cb792a4cf475892 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 15 Nov 2022 16:08:27 +0100 Subject: [PATCH 57/99] Measurement: Partially fixed the common gizmo raycaster for self-intersecting meshes --- src/slic3r/GUI/MeshUtils.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 0483d2bf0a..94375a6e34 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -409,6 +409,12 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& Vec3d direction; line_from_mouse_pos(mouse_pos, trafo, camera, point, direction); + if (rand()%100 == 0) { + int a=5; + int b=6; + int c=7; + } + std::vector hits = m_emesh.query_ray_hits(point, direction); if (hits.empty()) @@ -429,10 +435,10 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& // All hits are clipped. return false; } - if ((hits.size()-i) % 2 != 0) { + if (clipping_plane && (hits.size()-i) % 2 != 0) { // There is an odd number of unclipped hits - meaning the nearest must be from inside the mesh. // In that case, calculate intersection with the clipping place. - if (clipping_plane && was_clipping_plane_hit) { + if (was_clipping_plane_hit) { direction = direction + point; point = trafo * point; // transform to world coords direction = trafo * direction - point; From 075c24190691f90ac85d1544a295a80bbf26c4eb Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 08:53:02 +0100 Subject: [PATCH 58/99] Tech ENABLE_GIZMO_MEASURE_WORLD_COORDINATES set as default Fixed conflicts during rebase to master --- src/libslic3r/Measure.cpp | 48 -- src/libslic3r/Measure.hpp | 30 +- src/libslic3r/Technologies.hpp | 2 - src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 850 +++++++++-------------- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 26 +- src/slic3r/GUI/Selection.cpp | 2 - src/slic3r/GUI/Selection.hpp | 2 - 7 files changed, 323 insertions(+), 637 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 9b930df9aa..4e3bcaa822 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -47,9 +47,7 @@ public: std::optional get_feature(size_t face_idx, const Vec3d& point) const; std::vector> get_planes_triangle_indices() const; const std::vector& get_plane_features(unsigned int plane_id) const; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const TriangleMesh& get_mesh() const; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES private: void update_planes(); @@ -57,11 +55,7 @@ private: std::vector m_planes; std::vector m_face_to_plane; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES TriangleMesh m_mesh; -#else - const indexed_triangle_set& m_its; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; @@ -70,11 +64,7 @@ private: MeasuringImpl::MeasuringImpl(const indexed_triangle_set& its) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES : m_mesh(its) -#else -: m_its{its} -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES { update_planes(); extract_features(); @@ -87,17 +77,10 @@ void MeasuringImpl::update_planes() // Now we'll go through all the facets and append Points of facets sharing the same normal. // This part is still performed in mesh coordinate system. -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const size_t num_of_facets = m_mesh.its.indices.size(); m_face_to_plane.resize(num_of_facets, size_t(-1)); const std::vector face_normals = its_face_normals(m_mesh.its); const std::vector face_neighbors = its_face_neighbors(m_mesh.its); -#else - const size_t num_of_facets = m_its.indices.size(); - m_face_to_plane.resize(num_of_facets, size_t(-1)); - const std::vector face_normals = its_face_normals(m_its); - const std::vector face_neighbors = its_face_neighbors(m_its); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES std::vector facet_queue(num_of_facets, 0); int facet_queue_cnt = 0; const stl_normal* normal_ptr = nullptr; @@ -146,11 +129,7 @@ void MeasuringImpl::update_planes() assert(std::none_of(m_face_to_plane.begin(), m_face_to_plane.end(), [](size_t val) { return val == size_t(-1); })); // Now we will walk around each of the planes and save vertices which form the border. -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES SurfaceMesh sm(m_mesh.its); -#else - SurfaceMesh sm(m_its); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES for (int plane_id=0; plane_id < int(m_planes.size()); ++plane_id) { const auto& facets = m_planes[plane_id].facets; m_planes[plane_id].borders.clear(); @@ -532,12 +511,10 @@ const std::vector& MeasuringImpl::get_plane_features(unsigned in return m_planes[plane_id].surface_features; } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const TriangleMesh& MeasuringImpl::get_mesh() const { return this->m_mesh; } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES @@ -579,12 +556,10 @@ const std::vector& Measuring::get_plane_features(unsigned int pl return priv->get_plane_features(plane_id); } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const TriangleMesh& Measuring::get_mesh() const { return priv->get_mesh(); } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const AngleAndEdges AngleAndEdges::Dummy = { 0.0, Vec3d::Zero(), { Vec3d::Zero(), Vec3d::Zero() }, { Vec3d::Zero(), Vec3d::Zero() }, 0.0, true }; @@ -1184,29 +1159,6 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& return result; } -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -void DistAndPoints::transform(const Transform3d& trafo) { - from = trafo * from; - to = trafo * to; - dist = (to - from).norm(); -} - -void AngleAndEdges::transform(const Transform3d& trafo) { - const Vec3d old_e1 = e1.second - e1.first; - const Vec3d old_e2 = e2.second - e2.first; - center = trafo * center; - e1.first = trafo * e1.first; - e1.second = trafo * e1.second; - e2.first = trafo * e2.first; - e2.second = trafo * e2.second; - angle = std::acos(std::clamp(Measure::edge_direction(e1).dot(Measure::edge_direction(e2)), -1.0, 1.0)); - const Vec3d new_e1 = e1.second - e1.first; - const Vec3d new_e2 = e2.second - e2.first; - const double average_scale = 0.5 * (new_e1.norm() / old_e1.norm() + new_e2.norm() / old_e2.norm()); - radius = average_scale * radius; -} -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index 9cc380dd2b..3a1a4b89d9 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -13,9 +13,7 @@ struct indexed_triangle_set; namespace Slic3r { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES class TriangleMesh; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES namespace Measure { @@ -93,10 +91,7 @@ class MeasuringImpl; class Measuring { public: // Construct the measurement object on a given its. -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - // The its must remain valid and unchanged during the whole lifetime of the object. -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - explicit Measuring(const indexed_triangle_set& its); + explicit Measuring(const indexed_triangle_set& its); ~Measuring(); // Return a reference to a list of all features identified on the its. @@ -115,10 +110,8 @@ public: // Returns the surface features of the plane with the given index const std::vector& get_plane_features(unsigned int plane_id) const; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // Returns the mesh used for measuring const TriangleMesh& get_mesh() const; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES private: std::unique_ptr priv; @@ -130,10 +123,6 @@ struct DistAndPoints { double dist; Vec3d from; Vec3d to; - -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void transform(const Transform3d& trafo); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; struct AngleAndEdges { @@ -146,10 +135,6 @@ struct AngleAndEdges { double radius; bool coplanar; -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void transform(const Transform3d& trafo); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - static const AngleAndEdges Dummy; }; @@ -166,19 +151,6 @@ struct MeasurementResult { bool has_any_data() const { return angle.has_value() || distance_infinite.has_value() || distance_strict.has_value() || distance_xyz.has_value(); } - -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - void transform(const Transform3d& trafo) { - if (angle.has_value()) - angle->transform(trafo); - if (distance_infinite.has_value()) - distance_infinite->transform(trafo); - if (distance_strict.has_value()) { - distance_strict->transform(trafo); - distance_xyz = (distance_strict->to - distance_strict->from).cwiseAbs(); - } - } -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES }; // Returns distance/angle between two SurfaceFeatures. diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 759871c60d..f707b0f21d 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -64,8 +64,6 @@ // Enable picking using raytracing #define ENABLE_RAYCAST_PICKING (1 && ENABLE_LEGACY_OPENGL_REMOVAL) #define ENABLE_RAYCAST_PICKING_DEBUG (0 && ENABLE_RAYCAST_PICKING) -// Enable gizmo measure combining volumes meshes and passing them to the backend in world coordinates -#define ENABLE_GIZMO_MEASURE_WORLD_COORDINATES (1 && ENABLE_2_5_0_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 8cfbf634eb..35767121d7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -6,10 +6,6 @@ #include "slic3r/GUI/GUI_ObjectManipulation.hpp" -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" -#include "libslic3r/Model.hpp" -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES #include "libslic3r/PresetBundle.hpp" #include "libslic3r/MeasureUtils.hpp" @@ -370,13 +366,8 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) } } - if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) { + if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - // transform to world coordinates - m_measurement_result.transform(m_volume_matrix); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - } m_imgui->set_requires_extra_frame(); @@ -423,29 +414,12 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) void GLGizmoMeasure::data_changed() { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES update_if_needed(); -#else - const Selection& selection = m_parent.get_selection(); - const ModelObject* model_object = nullptr; - const ModelVolume* model_volume = nullptr; - if (selection.is_single_full_instance() || - selection.is_from_single_object() ) { - model_object = selection.get_model()->objects[selection.get_object_idx()]; - model_volume = model_object->volumes[selection.get_first_volume()->volume_idx()]; - } - if (model_object != m_old_model_object || model_volume != m_old_model_volume) - update_if_needed(); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_last_inv_zoom = 0.0f; m_last_plane_idx = -1; if (m_pending_scale) { m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - // transform to world coordinates - m_measurement_result.transform(m_volume_matrix); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_pending_scale = false; } else @@ -522,9 +496,7 @@ void GLGizmoMeasure::on_set_state() m_editing_distance = false; m_is_editing_distance_first_frame = true; m_measuring.reset(); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES m_raycaster.reset(); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } else { m_mode = EMode::FeatureSelection; @@ -541,13 +513,6 @@ void GLGizmoMeasure::on_set_state() } } -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -CommonGizmosDataID GLGizmoMeasure::on_get_requirements() const -{ - return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo) | int(CommonGizmosDataID::Raycaster)); -} -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - std::string GLGizmoMeasure::on_get_name() const { return _u8L("Measure"); @@ -558,15 +523,9 @@ bool GLGizmoMeasure::on_is_activable() const const Selection& selection = m_parent.get_selection(); bool res = (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) ? selection.is_single_full_instance() : -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier(); if (res) res &= !selection.contains_sinking_volumes(); -#else - selection.is_single_volume() || selection.is_single_volume_instance(); - if (res) - res &= !selection.get_first_volume()->is_sinking(); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES return res; } @@ -583,473 +542,390 @@ void GLGizmoMeasure::on_render() const Selection& selection = m_parent.get_selection(); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA && selection.is_single_full_instance()) || - (selection.is_single_volume() || selection.is_single_volume_instance())) { -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - update_if_needed(); + update_if_needed(); - const Camera& camera = wxGetApp().plater()->get_camera(); - const float inv_zoom = (float)camera.get_inv_zoom(); + const Camera& camera = wxGetApp().plater()->get_camera(); + const float inv_zoom = (float)camera.get_inv_zoom(); - Vec3f position_on_model; - Vec3f normal_on_model; - size_t model_facet_idx; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const bool mouse_on_object = m_raycaster->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); -#else - const bool mouse_on_object = m_c->raycaster()->raycasters().front()->unproject_on_mesh(m_mouse_pos, m_volume_matrix, camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const bool is_hovering_on_feature = (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) && m_hover_id != -1; + Vec3f position_on_model; + Vec3f normal_on_model; + size_t model_facet_idx; + const bool mouse_on_object = m_raycaster->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); + const bool is_hovering_on_feature = (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) && m_hover_id != -1; - auto update_circle = [this, inv_zoom]() { - if (m_last_inv_zoom != inv_zoom || m_last_circle != m_curr_feature) { - m_last_inv_zoom = inv_zoom; - m_last_circle = m_curr_feature; - m_circle.reset(); - const auto [center, radius, normal] = m_curr_feature->get_circle(); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); -#else - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), m_volume_matrix.cast()); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - m_circle.mesh_raycaster = std::make_unique(std::make_shared(circle_geometry.get_as_indexed_triangle_set())); - m_circle.model.init_from(std::move(circle_geometry)); - return true; - } - return false; - }; + auto update_circle = [this, inv_zoom]() { + if (m_last_inv_zoom != inv_zoom || m_last_circle != m_curr_feature) { + m_last_inv_zoom = inv_zoom; + m_last_circle = m_curr_feature; + m_circle.reset(); + const auto [center, radius, normal] = m_curr_feature->get_circle(); + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); + m_circle.mesh_raycaster = std::make_unique(std::make_shared(circle_geometry.get_as_indexed_triangle_set())); + m_circle.model.init_from(std::move(circle_geometry)); + return true; + } + return false; + }; - if (m_mode == EMode::FeatureSelection || m_mode == EMode::PointSelection) { - if ((m_hover_id == SELECTION_1_ID && boost::algorithm::istarts_with(m_selected_features.first.source, _u8L("Center"))) || - (m_hover_id == SELECTION_2_ID && boost::algorithm::istarts_with(m_selected_features.second.source, _u8L("Center")))) { - // Skip feature detection if hovering on a selected center - m_curr_feature.reset(); + if (m_mode == EMode::FeatureSelection || m_mode == EMode::PointSelection) { + if ((m_hover_id == SELECTION_1_ID && boost::algorithm::istarts_with(m_selected_features.first.source, _u8L("Center"))) || + (m_hover_id == SELECTION_2_ID && boost::algorithm::istarts_with(m_selected_features.second.source, _u8L("Center")))) { + // Skip feature detection if hovering on a selected center + m_curr_feature.reset(); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); + m_curr_point_on_feature_position.reset(); + } + else { + std::optional curr_feature = mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; + if (m_curr_feature != curr_feature || + (curr_feature.has_value() && curr_feature->get_type() == Measure::SurfaceFeatureType::Circle && (m_curr_feature != curr_feature || m_last_inv_zoom != inv_zoom))) { m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); - m_curr_point_on_feature_position.reset(); - } - else { - std::optional curr_feature = mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; - if (m_curr_feature != curr_feature || - (curr_feature.has_value() && curr_feature->get_type() == Measure::SurfaceFeatureType::Circle && (m_curr_feature != curr_feature || m_last_inv_zoom != inv_zoom))) { - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID); - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID); - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); - m_raycasters.clear(); - m_curr_feature = curr_feature; - if (!m_curr_feature.has_value()) - return; + m_raycasters.clear(); + m_curr_feature = curr_feature; + if (!m_curr_feature.has_value()) + return; - switch (m_curr_feature->get_type()) { - default: { assert(false); break; } - case Measure::SurfaceFeatureType::Point: - { - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); - break; - } - case Measure::SurfaceFeatureType::Edge: - { - m_raycasters.insert({ EDGE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID, *m_cylinder.mesh_raycaster) }); - if (m_curr_feature->get_extra_point().has_value()) - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); - break; - } - case Measure::SurfaceFeatureType::Circle: - { - update_circle(); - m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); - break; - } - case Measure::SurfaceFeatureType::Plane: - { - const auto [idx, normal, point] = m_curr_feature->get_plane(); - if (m_last_plane_idx != idx) { - m_last_plane_idx = idx; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const indexed_triangle_set& its = m_measuring->get_mesh().its; -#else - const indexed_triangle_set its = (m_old_model_volume != nullptr) ? m_old_model_volume->mesh().its : m_old_model_object->volumes.front()->mesh().its; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const std::vector> planes_triangles = m_measuring->get_planes_triangle_indices(); - GLModel::Geometry init_data = init_plane_data(its, planes_triangles, idx); - m_plane.reset(); - m_plane.mesh_raycaster = std::make_unique(std::make_shared(init_data.get_as_indexed_triangle_set())); - m_plane.model.init_from(std::move(init_data)); - } - - m_raycasters.insert({ PLANE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID, *m_plane.mesh_raycaster) }); - break; - } - } - } - } - } - - if (m_mode != EMode::PointSelection) - m_curr_point_on_feature_position.reset(); - else if (is_hovering_on_feature) { - auto position_on_feature = [this](int feature_type_id, const Camera& camera, std::function callback = nullptr) -> Vec3d { - auto it = m_raycasters.find(feature_type_id); - if (it != m_raycasters.end() && it->second != nullptr) { - Vec3f p; - Vec3f n; - const Transform3d& trafo = it->second->get_transform(); - bool res = it->second->get_raycaster()->closest_hit(m_mouse_pos, trafo, camera, p, n); - if (res) { - if (callback) - p = callback(p); - return trafo * p.cast(); - } - } - return Vec3d::Zero(); - }; - - if (m_curr_feature.has_value()) { - switch (m_curr_feature->get_type()) - { + switch (m_curr_feature->get_type()) { default: { assert(false); break; } case Measure::SurfaceFeatureType::Point: { - m_curr_point_on_feature_position = m_curr_feature->get_point(); + m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); break; } case Measure::SurfaceFeatureType::Edge: { - const std::optional extra = m_curr_feature->get_extra_point(); - if (extra.has_value() && m_hover_id == POINT_ID) - m_curr_point_on_feature_position = *extra; - else -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - m_curr_point_on_feature_position = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); -#else - m_curr_point_on_feature_position = m_volume_matrix.inverse() * position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + m_raycasters.insert({ EDGE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID, *m_cylinder.mesh_raycaster) }); + if (m_curr_feature->get_extra_point().has_value()) + m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); + break; + } + case Measure::SurfaceFeatureType::Circle: + { + update_circle(); + m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); + m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); break; } case Measure::SurfaceFeatureType::Plane: { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - m_curr_point_on_feature_position = position_on_feature(PLANE_ID, camera); -#else - m_curr_point_on_feature_position = m_volume_matrix.inverse() * position_on_feature(PLANE_ID, camera); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - break; - } - case Measure::SurfaceFeatureType::Circle: - { - const auto [center, radius, normal] = m_curr_feature->get_circle(); - if (m_hover_id == POINT_ID) - m_curr_point_on_feature_position = center; - else { - const Vec3d world_pof = position_on_feature(CIRCLE_ID, camera, [](const Vec3f& v) { return v; }); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Eigen::Hyperplane plane(normal, center); -#else - const Eigen::Hyperplane plane(m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal, m_volume_matrix * center); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d local_to_model_matrix = Geometry::translation_transform(center) * Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), normal); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Vec3d local_proj = local_to_model_matrix.inverse() * plane.projection(world_pof); -#else - const Vec3d local_proj = local_to_model_matrix.inverse() * m_volume_matrix.inverse() * plane.projection(world_pof); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - double angle = std::atan2(local_proj.y(), local_proj.x()); - if (angle < 0.0) - angle += 2.0 * double(M_PI); - - const Vec3d local_pos = radius * Vec3d(std::cos(angle), std::sin(angle), 0.0); - m_curr_point_on_feature_position = local_to_model_matrix * local_pos; + const auto [idx, normal, point] = m_curr_feature->get_plane(); + if (m_last_plane_idx != idx) { + m_last_plane_idx = idx; + const indexed_triangle_set& its = m_measuring->get_mesh().its; + const std::vector> planes_triangles = m_measuring->get_planes_triangle_indices(); + GLModel::Geometry init_data = init_plane_data(its, planes_triangles, idx); + m_plane.reset(); + m_plane.mesh_raycaster = std::make_unique(std::make_shared(init_data.get_as_indexed_triangle_set())); + m_plane.model.init_from(std::move(init_data)); } + + m_raycasters.insert({ PLANE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID, *m_plane.mesh_raycaster) }); break; } } } } - else { - if (m_curr_feature.has_value() && m_curr_feature->get_type() == Measure::SurfaceFeatureType::Circle) { - if (update_circle()) { - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); - auto it = m_raycasters.find(CIRCLE_ID); - if (it != m_raycasters.end()) - m_raycasters.erase(it); - m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); + } + + if (m_mode != EMode::PointSelection) + m_curr_point_on_feature_position.reset(); + else if (is_hovering_on_feature) { + auto position_on_feature = [this](int feature_type_id, const Camera& camera, std::function callback = nullptr) -> Vec3d { + auto it = m_raycasters.find(feature_type_id); + if (it != m_raycasters.end() && it->second != nullptr) { + Vec3f p; + Vec3f n; + const Transform3d& trafo = it->second->get_transform(); + bool res = it->second->get_raycaster()->closest_hit(m_mouse_pos, trafo, camera, p, n); + if (res) { + if (callback) + p = callback(p); + return trafo * p.cast(); } } + return Vec3d::Zero(); + }; + + if (m_curr_feature.has_value()) { + switch (m_curr_feature->get_type()) + { + default: { assert(false); break; } + case Measure::SurfaceFeatureType::Point: + { + m_curr_point_on_feature_position = m_curr_feature->get_point(); + break; + } + case Measure::SurfaceFeatureType::Edge: + { + const std::optional extra = m_curr_feature->get_extra_point(); + if (extra.has_value() && m_hover_id == POINT_ID) + m_curr_point_on_feature_position = *extra; + else + m_curr_point_on_feature_position = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); + break; + } + case Measure::SurfaceFeatureType::Plane: + { + m_curr_point_on_feature_position = position_on_feature(PLANE_ID, camera); + break; + } + case Measure::SurfaceFeatureType::Circle: + { + const auto [center, radius, normal] = m_curr_feature->get_circle(); + if (m_hover_id == POINT_ID) + m_curr_point_on_feature_position = center; + else { + const Vec3d world_pof = position_on_feature(CIRCLE_ID, camera, [](const Vec3f& v) { return v; }); + const Eigen::Hyperplane plane(normal, center); + const Transform3d local_to_model_matrix = Geometry::translation_transform(center) * Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), normal); + const Vec3d local_proj = local_to_model_matrix.inverse() * plane.projection(world_pof); + double angle = std::atan2(local_proj.y(), local_proj.x()); + if (angle < 0.0) + angle += 2.0 * double(M_PI); + + const Vec3d local_pos = radius * Vec3d(std::cos(angle), std::sin(angle), 0.0); + m_curr_point_on_feature_position = local_to_model_matrix * local_pos; + } + break; + } + } } + } + else { + if (m_curr_feature.has_value() && m_curr_feature->get_type() == Measure::SurfaceFeatureType::Circle) { + if (update_circle()) { + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); + auto it = m_raycasters.find(CIRCLE_ID); + if (it != m_raycasters.end()) + m_raycasters.erase(it); + m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); + } + } + } - if (!m_curr_feature.has_value() && !m_selected_features.first.feature.has_value()) - return; + if (!m_curr_feature.has_value() && !m_selected_features.first.feature.has_value()) + return; - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); - if (shader == nullptr) - return; + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; - shader->start_using(); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->start_using(); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_DEPTH_TEST)); - const bool old_cullface = ::glIsEnabled(GL_CULL_FACE); - glsafe(::glDisable(GL_CULL_FACE)); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_DEPTH_TEST)); + const bool old_cullface = ::glIsEnabled(GL_CULL_FACE); + glsafe(::glDisable(GL_CULL_FACE)); - const Transform3d& view_matrix = camera.get_view_matrix(); + const Transform3d& view_matrix = camera.get_view_matrix(); - auto set_matrix_uniforms = [shader, &view_matrix](const Transform3d& model_matrix) { - const Transform3d view_model_matrix = view_matrix * model_matrix; - shader->set_uniform("view_model_matrix", view_model_matrix); - const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); - shader->set_uniform("view_normal_matrix", view_normal_matrix); - }; + auto set_matrix_uniforms = [shader, &view_matrix](const Transform3d& model_matrix) { + const Transform3d view_model_matrix = view_matrix * model_matrix; + shader->set_uniform("view_model_matrix", view_model_matrix); + const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); + shader->set_uniform("view_normal_matrix", view_normal_matrix); + }; - auto set_emission_uniform = [this, shader](const ColorRGBA& color, bool hover) { - shader->set_uniform("emission_factor", (color == m_parent.get_selection().get_first_volume()->render_color) ? 0.0f : - hover ? 0.5f : 0.25f); - }; + auto set_emission_uniform = [this, shader](const ColorRGBA& color, bool hover) { + shader->set_uniform("emission_factor", (color == m_parent.get_selection().get_first_volume()->render_color) ? 0.0f : + hover ? 0.5f : 0.25f); + }; - auto render_feature = [this, set_matrix_uniforms, set_emission_uniform](const Measure::SurfaceFeature& feature, const std::vector& colors, - float inv_zoom, bool hover, bool update_raycasters_transform) { - switch (feature.get_type()) - { - default: { assert(false); break; } - case Measure::SurfaceFeatureType::Point: - { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d feature_matrix = Geometry::translation_transform(feature.get_point()) * Geometry::scale_transform(inv_zoom); -#else - const Vec3d position = TransformHelper::model_to_world(feature.get_point(), m_volume_matrix); - const Transform3d feature_matrix = Geometry::translation_transform(position) * Geometry::scale_transform(inv_zoom); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(feature_matrix); + auto render_feature = [this, set_matrix_uniforms, set_emission_uniform](const Measure::SurfaceFeature& feature, const std::vector& colors, + float inv_zoom, bool hover, bool update_raycasters_transform) { + switch (feature.get_type()) + { + default: { assert(false); break; } + case Measure::SurfaceFeatureType::Point: + { + const Transform3d feature_matrix = Geometry::translation_transform(feature.get_point()) * Geometry::scale_transform(inv_zoom); + set_matrix_uniforms(feature_matrix); + set_emission_uniform(colors.front(), hover); + m_sphere.model.set_color(colors.front()); + m_sphere.model.render(); + if (update_raycasters_transform) { + auto it = m_raycasters.find(POINT_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(feature_matrix); + } + break; + } + case Measure::SurfaceFeatureType::Circle: + { + const auto& [center, radius, normal] = feature.get_circle(); + // render center + if (update_raycasters_transform) { + const Transform3d center_matrix = Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom); + set_matrix_uniforms(center_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); m_sphere.model.render(); - if (update_raycasters_transform) { - auto it = m_raycasters.find(POINT_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(feature_matrix); - } - break; + auto it = m_raycasters.find(POINT_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(center_matrix); } - case Measure::SurfaceFeatureType::Circle: - { - const auto& [center, radius, normal] = feature.get_circle(); - // render center + // render circle + if (m_mode != EMode::CenterSelection) { + const Transform3d circle_matrix = Transform3d::Identity(); + set_matrix_uniforms(circle_matrix); if (update_raycasters_transform) { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d center_matrix = Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom); -#else - const Vec3d center_world = TransformHelper::model_to_world(center, m_volume_matrix); - const Transform3d center_matrix = Geometry::translation_transform(center_world) * Geometry::scale_transform(inv_zoom); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(center_matrix); + set_emission_uniform(colors.back(), hover); + m_circle.model.set_color(colors.back()); + m_circle.model.render(); + auto it = m_raycasters.find(CIRCLE_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(circle_matrix); + } + else { + GLModel circle; + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); + circle.init_from(std::move(circle_geometry)); + set_emission_uniform(colors.back(), hover); + circle.set_color(colors.back()); + circle.render(); + } + } + break; + } + case Measure::SurfaceFeatureType::Edge: + { + const auto& [from, to] = feature.get_edge(); + // render extra point + if (update_raycasters_transform) { + const std::optional extra = feature.get_extra_point(); + if (extra.has_value()) { + const Transform3d point_matrix = Geometry::translation_transform(*extra) * Geometry::scale_transform(inv_zoom); + set_matrix_uniforms(point_matrix); set_emission_uniform(colors.front(), hover); m_sphere.model.set_color(colors.front()); m_sphere.model.render(); auto it = m_raycasters.find(POINT_ID); if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(center_matrix); + it->second->set_transform(point_matrix); } - // render circle - if (m_mode != EMode::CenterSelection) { - const Transform3d circle_matrix = Transform3d::Identity(); - set_matrix_uniforms(circle_matrix); - if (update_raycasters_transform) { - set_emission_uniform(colors.back(), hover); - m_circle.model.set_color(colors.back()); - m_circle.model.render(); - auto it = m_raycasters.find(CIRCLE_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(circle_matrix); - } - else { - GLModel circle; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); -#else - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), m_volume_matrix.cast()); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - circle.init_from(std::move(circle_geometry)); - set_emission_uniform(colors.back(), hover); - circle.set_color(colors.back()); - circle.render(); - } - } - break; } - case Measure::SurfaceFeatureType::Edge: - { - const auto& [from, to] = feature.get_edge(); - // render extra point + // render edge + if (m_mode != EMode::CenterSelection) { + const Transform3d edge_matrix = Geometry::translation_transform(from) * + Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * + Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); + set_matrix_uniforms(edge_matrix); + set_emission_uniform(colors.back(), hover); + m_cylinder.model.set_color(colors.back()); + m_cylinder.model.render(); if (update_raycasters_transform) { - const std::optional extra = feature.get_extra_point(); - if (extra.has_value()) { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d point_matrix = Geometry::translation_transform(*extra) * Geometry::scale_transform(inv_zoom); -#else - const Vec3d extra_world = TransformHelper::model_to_world(*extra, m_volume_matrix); - const Transform3d point_matrix = Geometry::translation_transform(extra_world) * Geometry::scale_transform(inv_zoom); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(point_matrix); - set_emission_uniform(colors.front(), hover); - m_sphere.model.set_color(colors.front()); - m_sphere.model.render(); - auto it = m_raycasters.find(POINT_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(point_matrix); - } - } - // render edge - if (m_mode != EMode::CenterSelection) { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d edge_matrix = Geometry::translation_transform(from) * - Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * - Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); -#else - const Vec3d from_world = TransformHelper::model_to_world(from, m_volume_matrix); - const Vec3d to_world = TransformHelper::model_to_world(to, m_volume_matrix); - const Transform3d edge_matrix = Geometry::translation_transform(from_world) * - Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to_world - from_world) * - Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to_world - from_world).norm() }); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(edge_matrix); - set_emission_uniform(colors.back(), hover); - m_cylinder.model.set_color(colors.back()); - m_cylinder.model.render(); - if (update_raycasters_transform) { - auto it = m_raycasters.find(EDGE_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(edge_matrix); - } - } - break; - } - case Measure::SurfaceFeatureType::Plane: - { - // no need to render the plane in case it is rendered with the same color as the volume in the 3D scene - if (colors.front() != m_parent.get_selection().get_first_volume()->render_color) { - const auto& [idx, normal, pt] = feature.get_plane(); - assert(idx < m_plane_models_cache.size()); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(Transform3d::Identity()); -#else - set_matrix_uniforms(m_volume_matrix); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_emission_uniform(colors.front(), hover); - m_plane_models_cache[idx].set_color(colors.front()); - m_plane_models_cache[idx].render(); - } - if (update_raycasters_transform) { - auto it = m_raycasters.find(PLANE_ID); + auto it = m_raycasters.find(EDGE_ID); if (it != m_raycasters.end() && it->second != nullptr) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - it->second->set_transform(Transform3d::Identity()); -#else - it->second->set_transform(m_volume_matrix); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + it->second->set_transform(edge_matrix); } - break; } + break; + } + case Measure::SurfaceFeatureType::Plane: + { + // no need to render the plane in case it is rendered with the same color as the volume in the 3D scene + if (colors.front() != m_parent.get_selection().get_first_volume()->render_color) { + const auto& [idx, normal, pt] = feature.get_plane(); + assert(idx < m_plane_models_cache.size()); + set_matrix_uniforms(Transform3d::Identity()); + set_emission_uniform(colors.front(), hover); + m_plane_models_cache[idx].set_color(colors.front()); + m_plane_models_cache[idx].render(); } - }; + if (update_raycasters_transform) { + auto it = m_raycasters.find(PLANE_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(Transform3d::Identity()); + } + break; + } + } + }; - auto hover_selection_color = [this]() { - return !m_selected_features.first.feature.has_value() ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; - }; + auto hover_selection_color = [this]() { + return !m_selected_features.first.feature.has_value() ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; + }; - auto hovering_color = [this, hover_selection_color, &selection]() { - return (m_mode == EMode::PointSelection) ? selection.get_first_volume()->render_color : hover_selection_color(); - }; + auto hovering_color = [this, hover_selection_color, &selection]() { + return (m_mode == EMode::PointSelection) ? selection.get_first_volume()->render_color : hover_selection_color(); + }; - if (m_curr_feature.has_value()) { - std::vector colors; - if (m_selected_features.first.feature.has_value() && *m_curr_feature == *m_selected_features.first.feature) + if (m_curr_feature.has_value()) { + std::vector colors; + if (m_selected_features.first.feature.has_value() && *m_curr_feature == *m_selected_features.first.feature) + colors.emplace_back(hovering_color()); + else if (m_selected_features.second.feature.has_value() && *m_curr_feature == *m_selected_features.second.feature) + colors.emplace_back(hovering_color()); + else { + switch (m_curr_feature->get_type()) + { + default: { assert(false); break; } + case Measure::SurfaceFeatureType::Point: + { + colors.emplace_back(hover_selection_color()); + break; + } + case Measure::SurfaceFeatureType::Edge: + case Measure::SurfaceFeatureType::Circle: + { + colors.emplace_back((m_hover_id == POINT_ID) ? hover_selection_color() : hovering_color()); colors.emplace_back(hovering_color()); - else if (m_selected_features.second.feature.has_value() && *m_curr_feature == *m_selected_features.second.feature) + break; + } + case Measure::SurfaceFeatureType::Plane: + { colors.emplace_back(hovering_color()); - else { - switch (m_curr_feature->get_type()) - { - default: { assert(false); break; } - case Measure::SurfaceFeatureType::Point: - { - colors.emplace_back(hover_selection_color()); - break; - } - case Measure::SurfaceFeatureType::Edge: - case Measure::SurfaceFeatureType::Circle: - { - colors.emplace_back((m_hover_id == POINT_ID) ? hover_selection_color() : hovering_color()); - colors.emplace_back(hovering_color()); - break; - } - case Measure::SurfaceFeatureType::Plane: - { - colors.emplace_back(hovering_color()); - break; - } - } + break; } - - render_feature(*m_curr_feature, colors, inv_zoom, true, true); - } - - if (m_selected_features.first.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.first.feature)) { - const std::vector colors = { SELECTED_1ST_COLOR }; - render_feature(*m_selected_features.first.feature, colors, inv_zoom, m_hover_id == SELECTION_1_ID, false); - if (m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Point) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_1_ID; }); - if (it != m_selection_raycasters.end()) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - (*it)->set_transform(Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); -#else - (*it)->set_transform(m_volume_matrix * Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - } - } - if (m_selected_features.second.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.second.feature)) { - const std::vector colors = { SELECTED_2ND_COLOR }; - render_feature(*m_selected_features.second.feature, colors, inv_zoom, m_hover_id == SELECTION_2_ID, false); - if (m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Point) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); - if (it != m_selection_raycasters.end()) -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - (*it)->set_transform(Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); -#else - (*it)->set_transform(m_volume_matrix * Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } } - if (is_hovering_on_feature && m_curr_point_on_feature_position.has_value()) { - if (m_hover_id != POINT_ID) { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Transform3d matrix = Geometry::translation_transform(*m_curr_point_on_feature_position) * Geometry::scale_transform(inv_zoom); -#else - const Vec3d position = TransformHelper::model_to_world(*m_curr_point_on_feature_position, m_volume_matrix); - const Transform3d matrix = Geometry::translation_transform(position) * Geometry::scale_transform(inv_zoom); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - set_matrix_uniforms(matrix); - const ColorRGBA color = hover_selection_color(); - set_emission_uniform(color, true); - m_sphere.model.set_color(color); - m_sphere.model.render(); - } - } - - shader->stop_using(); - - if (old_cullface) - glsafe(::glEnable(GL_CULL_FACE)); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + render_feature(*m_curr_feature, colors, inv_zoom, true, true); } -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + + if (m_selected_features.first.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.first.feature)) { + const std::vector colors = { SELECTED_1ST_COLOR }; + render_feature(*m_selected_features.first.feature, colors, inv_zoom, m_hover_id == SELECTION_1_ID, false); + if (m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Point) { + auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), + [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_1_ID; }); + if (it != m_selection_raycasters.end()) + (*it)->set_transform(Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); + } + } + if (m_selected_features.second.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.second.feature)) { + const std::vector colors = { SELECTED_2ND_COLOR }; + render_feature(*m_selected_features.second.feature, colors, inv_zoom, m_hover_id == SELECTION_2_ID, false); + if (m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Point) { + auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), + [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); + if (it != m_selection_raycasters.end()) + (*it)->set_transform(Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); + } + } + + if (is_hovering_on_feature && m_curr_point_on_feature_position.has_value()) { + if (m_hover_id != POINT_ID) { + const Transform3d matrix = Geometry::translation_transform(*m_curr_point_on_feature_position) * Geometry::scale_transform(inv_zoom); + set_matrix_uniforms(matrix); + const ColorRGBA color = hover_selection_color(); + set_emission_uniform(color, true); + m_sphere.model.set_color(color); + m_sphere.model.render(); + } + } + + shader->stop_using(); + + if (old_cullface) + glsafe(::glEnable(GL_CULL_FACE)); render_dimensioning(); } @@ -1066,7 +942,6 @@ void GLGizmoMeasure::update_if_needed() } }; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES auto do_update = [this, update_plane_models_cache](const std::vector& volumes_cache, const Selection& selection) { TriangleMesh composite_mesh; for (const auto& vol : volumes_cache) { @@ -1083,36 +958,11 @@ void GLGizmoMeasure::update_if_needed() m_raycaster.reset(new MeshRaycaster(std::make_shared(m_measuring->get_mesh()))); m_volumes_cache = volumes_cache; }; -#else - auto do_update = [this, update_plane_models_cache](const ModelObject* object, const ModelVolume* volume) { - const indexed_triangle_set& its = (volume != nullptr) ? volume->mesh().its : object->volumes.front()->mesh().its; - m_measuring.reset(new Measure::Measuring(its)); - - update_plane_models_cache(its); - - // Let's save what we calculated it from: - m_volumes_matrices.clear(); - m_volumes_types.clear(); - m_first_instance_scale = Vec3d::Ones(); - m_first_instance_mirror = Vec3d::Ones(); - if (object != nullptr) { - for (const ModelVolume* vol : object->volumes) { - m_volumes_matrices.push_back(vol->get_matrix()); - m_volumes_types.push_back(vol->type()); - } - m_first_instance_scale = object->instances.front()->get_scaling_factor(); - m_first_instance_mirror = object->instances.front()->get_mirror(); - } - m_old_model_object = object; - m_old_model_volume = volume; - }; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Selection& selection = m_parent.get_selection(); if (selection.is_empty()) return; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Selection::IndicesList& idxs = selection.get_volume_idxs(); std::vector volumes_cache; volumes_cache.reserve(idxs.size()); @@ -1130,36 +980,6 @@ void GLGizmoMeasure::update_if_needed() if (m_measuring == nullptr || m_volumes_cache != volumes_cache) do_update(volumes_cache, selection); -#else - m_volume_matrix = selection.get_first_volume()->world_matrix(); - - const ModelObject* mo = m_c->selection_info()->model_object(); - const ModelVolume* mv = m_c->selection_info()->model_volume(); - if (m_state != On || (mo == nullptr && mv == nullptr)) - return; - - if (mo == nullptr) - mo = mv->get_object(); - - if (mo->instances.empty()) - return; - - if (!m_measuring || mo != m_old_model_object || mv != m_old_model_volume || mo->volumes.size() != m_volumes_matrices.size()) - do_update(mo, mv); - - // We want to recalculate when the scale changes - some planes could (dis)appear. - if (!mo->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale) || - !mo->instances.front()->get_mirror().isApprox(m_first_instance_mirror)) - do_update(mo, mv); - - for (unsigned int i = 0; i < mo->volumes.size(); ++i) { - if (!mo->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i]) || - mo->volumes[i]->type() != m_volumes_types[i]) { - do_update(mo, mv); - break; - } - } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES } void GLGizmoMeasure::disable_scene_raycasters() @@ -1279,7 +1099,6 @@ void GLGizmoMeasure::render_dimensioning() const double ratio = new_value / old_value; wxGetApp().plater()->take_snapshot(_L("Scale")); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES struct TrafoData { double ratio; @@ -1333,7 +1152,6 @@ void GLGizmoMeasure::render_dimensioning() const TrafoData trafo_data(ratio, m_parent.get_selection().get_bounding_box().center()); scale_feature(*m_selected_features.first.feature, trafo_data); scale_feature(*m_selected_features.second.feature, trafo_data); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES TransformationType type; type.set_world(); @@ -1392,14 +1210,7 @@ void GLGizmoMeasure::render_dimensioning() auto point_edge = [this, shader](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2) { assert(f1.get_type() == Measure::SurfaceFeatureType::Point && f2.get_type() == Measure::SurfaceFeatureType::Edge); std::pair e = f2.get_edge(); - // Transform to world coordinates -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - e.first = TransformHelper::model_to_world(e.first, m_volume_matrix); - e.second = TransformHelper::model_to_world(e.second, m_volume_matrix); -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const Vec3d v_proj = m_measurement_result.distance_infinite->to; - const Vec3d e1e2 = e.second - e.first; const Vec3d v_proje1 = v_proj - e.first; const bool on_e1_side = v_proje1.dot(e1e2) < -EPSILON; @@ -1677,21 +1488,12 @@ void GLGizmoMeasure::render_debug_dialog() { case Measure::SurfaceFeatureType::Point: { -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(item.feature->get_point()), ImGui::GetStyleColorVec4(ImGuiCol_Text)); -#else - const Vec3d position = m_volume_matrix * item.feature->get_point(); - add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(position), ImGui::GetStyleColorVec4(ImGuiCol_Text)); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES break; } case Measure::SurfaceFeatureType::Edge: { auto [from, to] = item.feature->get_edge(); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - from = m_volume_matrix * from; - to = m_volume_matrix * to; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(from), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(to), ImGui::GetStyleColorVec4(ImGuiCol_Text)); break; @@ -1699,10 +1501,6 @@ void GLGizmoMeasure::render_debug_dialog() case Measure::SurfaceFeatureType::Plane: { auto [idx, normal, origin] = item.feature->get_plane(); -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - origin = m_volume_matrix * origin; - normal = m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(origin), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_value", ImGuiWrapper::COL_ORANGE_LIGHT, format_double(idx), ImGui::GetStyleColorVec4(ImGuiCol_Text)); @@ -1711,13 +1509,7 @@ void GLGizmoMeasure::render_debug_dialog() case Measure::SurfaceFeatureType::Circle: { auto [center, radius, normal] = item.feature->get_circle(); -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); -#else - const Vec3d on_circle = m_volume_matrix * (center + radius * Measure::get_orthogonal(normal, true)); - center = m_volume_matrix * center; - normal = (m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal).normalized(); -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES radius = (on_circle - center).norm(); add_strings_row_to_table(*m_imgui, "m_pt1", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(center), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table(*m_imgui, "m_pt2", ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index fbbf30da78..9699d73cc8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -6,16 +6,10 @@ #include "slic3r/GUI/GUI_Utils.hpp" #include "slic3r/GUI/MeshUtils.hpp" #include "libslic3r/Measure.hpp" -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES #include "libslic3r/Model.hpp" -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES namespace Slic3r { -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES -class ModelVolume; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - enum class ModelVolumeType : int; namespace Measure { class Measuring; } @@ -74,7 +68,6 @@ class GLGizmoMeasure : public GLGizmoBase } }; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES struct VolumeCacheItem { const ModelObject* object{ nullptr }; @@ -89,7 +82,6 @@ class GLGizmoMeasure : public GLGizmoBase }; std::vector m_volumes_cache; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES EMode m_mode{ EMode::FeatureSelection }; Measure::MeasurementResult m_measurement_result; @@ -108,13 +100,10 @@ class GLGizmoMeasure : public GLGizmoBase }; Dimensioning m_dimensioning; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // Uses a standalone raycaster and not the shared one because of the // difference in how the mesh is updated std::unique_ptr m_raycaster; -#else - Transform3d m_volume_matrix{ Transform3d::Identity() }; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES + std::vector m_plane_models_cache; std::map> m_raycasters; std::vector> m_selection_raycasters; @@ -129,21 +118,11 @@ class GLGizmoMeasure : public GLGizmoBase std::vector m_scene_raycasters; // These hold information to decide whether recalculation is necessary: -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - std::vector m_volumes_matrices; - std::vector m_volumes_types; - Vec3d m_first_instance_scale{ Vec3d::Ones() }; - Vec3d m_first_instance_mirror{ Vec3d::Ones() }; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES float m_last_inv_zoom{ 0.0f }; std::optional m_last_circle; int m_last_plane_idx{ -1 }; bool m_mouse_left_down{ false }; // for detection left_up of this gizmo -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - const ModelObject* m_old_model_object{ nullptr }; - const ModelVolume* m_old_model_volume{ nullptr }; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES Vec2d m_mouse_pos{ Vec2d::Zero() }; @@ -186,9 +165,6 @@ protected: bool on_is_activable() const override; void on_render() override; void on_set_state() override; -#if !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES - CommonGizmosDataID on_get_requirements() const override; -#endif // !ENABLE_GIZMO_MEASURE_WORLD_COORDINATES virtual void on_render_input_window(float x, float y, float bottom_limit) override; virtual void on_register_raycasters_for_picking() override; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 0e893fb16c..c3a7ec18be 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -613,7 +613,6 @@ bool Selection::contains_any_volume(const std::vector& volume_idxs return false; } -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES bool Selection::contains_sinking_volumes(bool ignore_modifiers) const { for (const GLVolume* v : *m_volumes) { @@ -624,7 +623,6 @@ bool Selection::contains_sinking_volumes(bool ignore_modifiers) const } return false; } -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES bool Selection::matches(const std::vector& volume_idxs) const { diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index cf9d26fc7d..6468f6a87d 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -338,10 +338,8 @@ public: bool contains_all_volumes(const std::vector& volume_idxs) const; // returns true if the selection contains at least one of the given indices bool contains_any_volume(const std::vector& volume_idxs) const; -#if ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // returns true if the selection contains any sinking volume bool contains_sinking_volumes(bool ignore_modifiers = true) const; -#endif // ENABLE_GIZMO_MEASURE_WORLD_COORDINATES // returns true if the selection contains all and only the given indices bool matches(const std::vector& volume_idxs) const; From 6dd8199edf518f5a83ee2de7d338b78c002f477d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 09:38:19 +0100 Subject: [PATCH 59/99] Gizmo measure - Fixed orientation of arrows in arc dimensioning --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 35767121d7..423c23edd2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1295,7 +1295,7 @@ void GLGizmoMeasure::render_dimensioning() const double angle = (endpoint_id == 1) ? 0.0 : step * double(resolution); const Vec3d position_model = Geometry::translation_transform(center) * (draw_radius * (Eigen::Quaternion(Eigen::AngleAxisd(angle, normal)) * e1_unit)); const Vec3d direction_model = (endpoint_id == 1) ? -normal.cross(position_model - center).normalized() : normal.cross(position_model - center).normalized(); - const auto qz = Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), normal); + const auto qz = Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), (endpoint_id == 1) ? normal : -normal); const auto qx = Eigen::Quaternion::FromTwoVectors(qz * Vec3d::UnitX(), direction_model); const Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::translation_transform(position_model) * qx * qz * Geometry::scale_transform(camera.get_inv_zoom()); From e6b2467f44623f59cba5ca8355eb5484ff8744ee Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 09:42:55 +0100 Subject: [PATCH 60/99] Fixed warnings --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 423c23edd2..b2edc0b979 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1118,7 +1118,7 @@ void GLGizmoMeasure::render_dimensioning() } }; - auto scale_feature = [this](Measure::SurfaceFeature& feature, const TrafoData& trafo_data) { + auto scale_feature = [](Measure::SurfaceFeature& feature, const TrafoData& trafo_data) { switch (feature.get_type()) { case Measure::SurfaceFeatureType::Point: @@ -1146,6 +1146,7 @@ void GLGizmoMeasure::render_dimensioning() feature = Measure::SurfaceFeature(Measure::SurfaceFeatureType::Plane, normal, trafo_data.transform(origin), std::nullopt, idx); break; } + default: { break; } } }; From 832b0a69e8efea32de28f44d098df6275f0310ee Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 09:46:50 +0100 Subject: [PATCH 61/99] Fixed warnings --- src/libslic3r/Measure.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 4e3bcaa822..ffb8f953a0 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -291,14 +291,14 @@ void MeasuringImpl::extract_features() // point happened to be inside the segment. The discrimination of too small segments // will follow, so we need a complete picture before that. if (circles_idxs.size() > 1 - && circles_idxs.back().second == angles.size()-1 + && circles_idxs.back().second == (int)angles.size()-1 && circles_idxs.front().first == 0) { // Possibly the same circle. Check that the angle and length criterion holds along the combined segment. bool same = true; double last_len = -1.; double last_angle = 0.; for (int i=circles_idxs.back().first + 1; i != circles_idxs.front().second; ++i) { - if (i == angles.size()) + if (i == (int)angles.size()) i = 1; if (last_len == -1.) { last_len = lengths[i]; @@ -347,12 +347,12 @@ void MeasuringImpl::extract_features() for (int i=int(circles_idxs.size())-1; i>=0; --i) { const auto& [start, end] = circles_idxs[i]; int N = start >= 0 - ? end - start + (start == 0 && end == border.size()-1 ? 0 : 1) // last point is the same as first + ? end - start + (start == 0 && end == (int)border.size()-1 ? 0 : 1) // last point is the same as first : end + (border.size() + start); if (N < 5) { circles.erase(circles.begin() + i); circles_idxs.erase(circles_idxs.begin() + i); - } else if (N <= 8 && start == 0 && end == border.size()-1) { + } else if (N <= 8 && start == 0 && end == (int)border.size()-1) { // This is a regular 5-8 polygon. Add the edges as edges with a special // point and remove the circle. Leave the indices in circles_idxs, so // the edges are not picked up again later. From ce46a1d03d21654a8a891a9eee295ea6617eda4c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 10:04:25 +0100 Subject: [PATCH 62/99] Removed debug code --- src/slic3r/GUI/MeshUtils.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 94375a6e34..68572c801e 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -409,12 +409,6 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& Vec3d direction; line_from_mouse_pos(mouse_pos, trafo, camera, point, direction); - if (rand()%100 == 0) { - int a=5; - int b=6; - int c=7; - } - std::vector hits = m_emesh.query_ray_hits(point, direction); if (hits.empty()) From 305ea0da27ea499230d4f4d6ee7b7e929f60ecc3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 12:04:38 +0100 Subject: [PATCH 63/99] Gizmo measure - Fixed angle for perpendicular edge-plane use case --- src/libslic3r/Measure.cpp | 53 +++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index ffb8f953a0..8213f9778d 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -29,6 +29,21 @@ static std::pair get_center_and_radius(const std::vector& return std::make_pair(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius); } +static std::array orthonormal_basis(const Vec3d& v) +{ + std::array ret; + ret[2] = v.normalized(); + int index; + ret[2].maxCoeff(&index); + switch (index) + { + case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; } + case 1: { ret[0] = Vec3d(0.0, ret[2].z(), -ret[2].y()).normalized(); break; } + case 2: { ret[0] = Vec3d(-ret[2].z(), 0.0, ret[2].x()).normalized(); break; } + } + ret[1] = ret[2].cross(ret[0]).normalized(); + return ret; +} @@ -630,8 +645,8 @@ static AngleAndEdges angle_edge_edge(const std::pair& e1, const st static AngleAndEdges angle_edge_plane(const std::pair& e, const std::tuple& p) { const auto& [idx, normal, origin] = p; - const Vec3d e1e2_unit = edge_direction(e); - if (are_parallel(e1e2_unit, normal) || are_perpendicular(e1e2_unit, normal)) + Vec3d e1e2_unit = edge_direction(e); + if (are_perpendicular(e1e2_unit, normal)) return AngleAndEdges::Dummy; // ensure the edge is pointing away from the intersection @@ -643,8 +658,22 @@ static AngleAndEdges angle_edge_plane(const std::pair& e, const st // then verify edge direction and revert it, if needed Vec3d e1 = e.first; Vec3d e2 = e.second; - if ((e1 - inters).squaredNorm() > (e2 - inters).squaredNorm()) + if ((e1 - inters).squaredNorm() > (e2 - inters).squaredNorm()) { std::swap(e1, e2); + e1e2_unit = -e1e2_unit; + } + + if (are_parallel(e1e2_unit, normal)) { + const std::array basis = orthonormal_basis(e1e2_unit); + const double radius = (0.5 * (e1 + e2) - inters).norm(); + const Vec3d edge_on_plane_dir = (basis[1].dot(origin - inters) >= 0.0) ? basis[1] : -basis[1]; + std::pair edge_on_plane = std::make_pair(inters, inters + radius * edge_on_plane_dir); + if (!inters.isApprox(e1)) { + edge_on_plane.first += radius * edge_on_plane_dir; + edge_on_plane.second += radius * edge_on_plane_dir; + } + return AngleAndEdges(0.5 * double(PI), inters, std::make_pair(e1, e2), edge_on_plane, radius, inters.isApprox(e1)); + } const Vec3d e1e2 = e2 - e1; const double e1e2_len = e1e2.norm(); @@ -773,7 +802,8 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// - } else if (f1.get_type() == SurfaceFeatureType::Edge) { + } + else if (f1.get_type() == SurfaceFeatureType::Edge) { if (f2.get_type() == SurfaceFeatureType::Edge) { std::vector distances; @@ -900,21 +930,6 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& const Vec3d D = c1 - c0; if (!are_parallel(n0, n1)) { - auto orthonormal_basis = [](const Vec3d& v) { - std::array ret; - ret[2] = v.normalized(); - int index; - ret[2].maxCoeff(&index); - switch (index) - { - case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; } - case 1: { ret[0] = Vec3d(0.0, ret[2].z(), -ret[2].y()).normalized(); break; } - case 2: { ret[0] = Vec3d(-ret[2].z(), 0.0, ret[2].x()).normalized(); break; } - } - ret[1] = ret[2].cross(ret[0]).normalized(); - return ret; - }; - // Get parameters for constructing the degree-8 polynomial phi. const double one = 1.0; const double two = 2.0; From 89bae8606b774f505f21831d4c96b8d26b8a0445 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 15:44:01 +0100 Subject: [PATCH 64/99] Removed debug code --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index b2edc0b979..1d71232fb0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -396,7 +396,6 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) else if (mouse_event.RightDown()) { // let the event pass through to allow panning/rotating the 3D scene if ((m_mode != EMode::CenterSelection && mouse_event.CmdDown()) || (m_mode == EMode::CenterSelection && m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID)) { - std::cout << "RightDown -> false\n"; return false; } From 534d0353eb7b473284443a3424b5bb50fc4062f3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 18 Nov 2022 08:42:47 +0100 Subject: [PATCH 65/99] Gizmo measure - Draw background for dimensioning labels --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 1d71232fb0..2f04e43a64 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1071,8 +1071,17 @@ void GLGizmoMeasure::render_dimensioning() ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 1.0f, 1.0f }); m_imgui->begin(std::string("distance"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration); + ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); ImGui::AlignTextToFramePadding(); - m_imgui->text(curr_value_str + " " + units); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 pos = ImGui::GetCursorScreenPos(); + const std::string txt = curr_value_str + " " + units; + ImVec2 txt_size = ImGui::CalcTextSize(txt.c_str()); + const ImGuiStyle& style = ImGui::GetStyle(); + draw_list->AddRectFilled({ pos.x - style.FramePadding.x, pos.y + style.FramePadding.y }, { pos.x + txt_size.x + 2.0f * style.FramePadding.x , pos.y + txt_size.y + 2.0f * style.FramePadding.y }, + ImGuiWrapper::to_ImU32(ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f))); + ImGui::SetCursorScreenPos({ pos.x + style.FramePadding.x, pos.y }); + m_imgui->text(txt); ImGui::SameLine(); if (m_imgui->image_button(ImGui::SliderFloatEditBtnIcon, _L("Edit to scale"))) { m_editing_distance = true; @@ -1345,7 +1354,16 @@ void GLGizmoMeasure::render_dimensioning() ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); m_imgui->begin(_L("##angle"), ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); - m_imgui->text(format_double(Geometry::rad2deg(angle)) + "°"); + ImGui::AlignTextToFramePadding(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 pos = ImGui::GetCursorScreenPos(); + const std::string txt = format_double(Geometry::rad2deg(angle)) + "°"; + ImVec2 txt_size = ImGui::CalcTextSize(txt.c_str()); + const ImGuiStyle& style = ImGui::GetStyle(); + draw_list->AddRectFilled({ pos.x - style.FramePadding.x, pos.y + style.FramePadding.y }, { pos.x + txt_size.x + 2.0f * style.FramePadding.x , pos.y + txt_size.y + 2.0f * style.FramePadding.y }, + ImGuiWrapper::to_ImU32(ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f))); + ImGui::SetCursorScreenPos({ pos.x + style.FramePadding.x, pos.y }); + m_imgui->text(txt); m_imgui->end(); ImGui::PopStyleVar(); }; From 1ba80257028a844cc75ca927c0363195f8ceb641 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 18 Nov 2022 10:53:42 +0100 Subject: [PATCH 66/99] Gizmo measure - Show diameter of selected circles into imgui dialog --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 2f04e43a64..ac957887dc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1789,10 +1789,23 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ImGui::Separator(); const ImGuiTableFlags flags = ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersH; if (ImGui::BeginTable("Selection", 2, flags)) { - add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 1:", ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR), m_selected_features.first.feature.has_value() ? - m_selected_features.first.source : _u8L("None"), ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR)); - add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 2:", ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR), m_selected_features.second.feature.has_value() ? - m_selected_features.second.source : _u8L("None"), ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR)); + auto format_item_text = [use_inches, &units](const SelectedFeatures::Item& item) { + std::string txt = item.feature.has_value() ? item.source : _u8L("None"); + if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) { + auto [center, radius, normal] = item.feature->get_circle(); + const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); + radius = (on_circle - center).norm(); + if (use_inches) + radius = ObjectManipulation::mm_to_in * radius; + txt += " (" + _u8L("Diameter:") + " " + format_double(2.0 * radius) + units + ")"; + } + return txt; + }; + + add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 1:", ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR), format_item_text(m_selected_features.first), + ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR)); + add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 2:", ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR), format_item_text(m_selected_features.second), + ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR)); ImGui::EndTable(); } From 62d683b50c0d3b5c93af290a825036070ac273d6 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 18 Nov 2022 11:17:20 +0100 Subject: [PATCH 67/99] Removed commented out code --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 104 ----------------------- 1 file changed, 104 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index ac957887dc..358ccd87f3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1682,110 +1682,6 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit const bool use_inches = wxGetApp().app_config->get("use_inches") == "1"; const std::string units = use_inches ? " " + _u8L("in") : " " + _u8L("mm"); - //const Measure::SurfaceFeatureType feature_type = m_curr_feature.has_value() ? m_curr_feature->get_type() : Measure::SurfaceFeatureType::Undef; - //bool data_text_set = false; - //ImGui::Separator(); - //if (feature_type != Measure::SurfaceFeatureType::Undef) { - // if (m_mode == EMode::FeatureSelection) { - // m_imgui->text(surface_feature_type_as_string(feature_type)); - // data_text_set = true; - // } - // else if (m_mode == EMode::PointSelection) { - // if (m_hover_id != -1 && m_curr_point_on_feature_position.has_value()) { - // m_imgui->text(point_on_feature_type_as_string(feature_type, m_hover_id)); - // data_text_set = true; - // } - // } - // else if (m_mode == EMode::CenterSelection) { - // if (m_hover_id != -1 && m_curr_point_on_feature_position.has_value()) { - // m_imgui->text(center_on_feature_type_as_string(feature_type)); - // data_text_set = true; - // } - // } - //} - //if (!data_text_set) - // m_imgui->text(_u8L("No feature")); - - //const unsigned int max_data_row_count = 3; - //unsigned int data_row_count = 0; - //if (ImGui::BeginTable("Data", 2)) { - // if (m_mode == EMode::FeatureSelection) { - // switch (feature_type) - // { - // default: { break; } - // case Measure::SurfaceFeatureType::Point: - // { - // Vec3d position = m_volume_matrix * m_curr_feature->get_point(); - // if (use_inches) - // position = ObjectManipulation::mm_to_in * position; - // add_strings_row_to_table(*m_imgui, _u8L("Position"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(position), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 1; - // break; - // } - // case Measure::SurfaceFeatureType::Edge: - // { - // auto [from, to] = m_curr_feature->get_edge(); - // from = m_volume_matrix * from; - // to = m_volume_matrix * to; - // if (use_inches) { - // from = ObjectManipulation::mm_to_in * from; - // to = ObjectManipulation::mm_to_in * to; - // } - // add_strings_row_to_table(*m_imgui, _u8L("From"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(from), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("To"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(to), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("Length"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double((to - from).norm()) + units, ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 3; - // break; - // } - // case Measure::SurfaceFeatureType::Circle: - // { - // auto [center, radius, normal] = m_curr_feature->get_circle(); - // // generic point on circle, used to recalculate radius after transformation - // const Vec3d on_circle = m_volume_matrix * (center + radius * Measure::get_orthogonal(normal, true)); - // center = m_volume_matrix * center; - // normal = (m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal).normalized(); - // radius = (on_circle - center).norm(); - // if (use_inches) { - // center = ObjectManipulation::mm_to_in * center; - // radius = ObjectManipulation::mm_to_in * radius; - // } - // add_strings_row_to_table(*m_imgui, _u8L("Center"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(center), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("Radius"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(radius) + units, ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("Normal"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 3; - // break; - // } - // case Measure::SurfaceFeatureType::Plane: - // { - // auto [idx, normal, origin] = m_curr_feature->get_plane(); - // origin = m_volume_matrix * origin; - // normal = m_volume_matrix.matrix().block(0, 0, 3, 3).inverse().transpose() * normal; - // if (use_inches) - // origin = ObjectManipulation::mm_to_in * origin; - // add_strings_row_to_table(*m_imgui, _u8L("Origin"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(origin), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // add_strings_row_to_table(*m_imgui, _u8L("Normal"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(normal), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 2; - // break; - // } - // } - // } - // else { - // if (m_hover_id != -1 && m_curr_point_on_feature_position.has_value()) { - // Vec3d position = m_volume_matrix * *m_curr_point_on_feature_position; - // if (use_inches) - // position = ObjectManipulation::mm_to_in * position; - // add_strings_row_to_table(*m_imgui, _u8L("Position"), ImGuiWrapper::COL_ORANGE_LIGHT, format_vec3(position), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // data_row_count = 1; - // } - // } - - // // add dummy rows to keep dialog size fixed - // for (unsigned int i = data_row_count; i < max_data_row_count; ++i) { - // add_strings_row_to_table(*m_imgui, " ", ImGuiWrapper::COL_ORANGE_LIGHT, " ", ImGui::GetStyleColorVec4(ImGuiCol_Text)); - // } - // ImGui::EndTable(); - //} - ImGui::Separator(); const ImGuiTableFlags flags = ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersH; if (ImGui::BeginTable("Selection", 2, flags)) { From cf2a7608d3e35e21c1e49bdaa428519f3afe8c98 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 18 Nov 2022 14:53:19 +0100 Subject: [PATCH 68/99] Gizmo measure - Render dimensioning thicker main lines --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 72 +++++++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 358ccd87f3..d85408f99c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1006,7 +1006,7 @@ void GLGizmoMeasure::render_dimensioning() if (shader == nullptr) return; - auto point_point = [this, shader](const Vec3d& v1, const Vec3d& v2, float distance) { + auto point_point = [this, &shader](const Vec3d& v1, const Vec3d& v2, float distance) { if ((v2 - v1).squaredNorm() < 0.000001 || distance < 0.001f) return; @@ -1036,6 +1036,25 @@ void GLGizmoMeasure::render_dimensioning() const Transform3d ss_to_ndc_matrix = TransformHelper::ndc_to_ss_matrix_inverse(viewport); +#if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_core_profile()) { + shader->stop_using(); + + shader = wxGetApp().get_shader("dashed_thick_lines"); + if (shader == nullptr) + return; + + shader->start_using(); + shader->set_uniform("projection_matrix", Transform3d::Identity()); + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 1.0f); + shader->set_uniform("gap_size", 0.0f); + } + else +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glLineWidth(2.0f)); + // stem shader->set_uniform("view_model_matrix", overlap ? ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss * Geometry::translation_transform(-2.0 * TRIANGLE_HEIGHT * Vec3d::UnitX()) * Geometry::scale_transform({ v12ss_len + 4.0 * TRIANGLE_HEIGHT, 1.0f, 1.0f }) : @@ -1043,6 +1062,20 @@ void GLGizmoMeasure::render_dimensioning() m_dimensioning.line.set_color(ColorRGBA::WHITE()); m_dimensioning.line.render(); +#if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_core_profile()) { + shader->stop_using(); + + shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + shader->start_using(); + } + else +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glLineWidth(1.0f)); + // arrow 1 shader->set_uniform("view_model_matrix", overlap ? ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss : @@ -1251,7 +1284,7 @@ void GLGizmoMeasure::render_dimensioning() } }; - auto arc_edge_edge = [this, shader](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2, double radius = 0.0) { + auto arc_edge_edge = [this, &shader](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2, double radius = 0.0) { assert(f1.get_type() == Measure::SurfaceFeatureType::Edge && f2.get_type() == Measure::SurfaceFeatureType::Edge); if (!m_measurement_result.angle.has_value()) return; @@ -1293,12 +1326,45 @@ void GLGizmoMeasure::render_dimensioning() m_dimensioning.arc.init_from(std::move(init_data)); } - // arc const Camera& camera = wxGetApp().plater()->get_camera(); +#if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_core_profile()) { + shader->stop_using(); + + shader = wxGetApp().get_shader("dashed_thick_lines"); + if (shader == nullptr) + return; + + shader->start_using(); + shader->set_uniform("projection_matrix", Transform3d::Identity()); + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 1.0f); + shader->set_uniform("gap_size", 0.0f); + } + else +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glLineWidth(2.0f)); + + // arc shader->set_uniform("projection_matrix", camera.get_projection_matrix()); shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::translation_transform(center)); m_dimensioning.arc.render(); +#if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_core_profile()) { + shader->stop_using(); + + shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + shader->start_using(); + } + else +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glLineWidth(1.0f)); + // arrows auto render_arrow = [this, shader, &camera, &normal, ¢er, &e1_unit, draw_radius, step, resolution](unsigned int endpoint_id) { const double angle = (endpoint_id == 1) ? 0.0 : step * double(resolution); From 5d6346f27508b35c58157b9fd11a684971183e73 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 08:37:58 +0100 Subject: [PATCH 69/99] Gizmo Measure - When CTRL+dragging to pan/rotate the scene, do not select the hovered feature, if any --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index d85408f99c..77d816aa76 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -254,6 +254,7 @@ GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filen bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) { m_mouse_pos = { double(mouse_event.GetX()), double(mouse_event.GetY()) }; + m_dragging = false; if (mouse_event.Moving()) { // only for sure @@ -261,6 +262,8 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) return false; } else if (mouse_event.Dragging()) { + m_dragging = true; + // Enable/Disable panning/rotating the 3D scene // Ctrl is pressed or the mouse is not hovering a selected volume bool unlock_dragging = mouse_event.CmdDown() || (m_hover_id == -1 && !m_parent.get_selection().contains_volume(m_parent.get_first_hover_volume_idx())); @@ -578,7 +581,9 @@ void GLGizmoMeasure::on_render() m_curr_point_on_feature_position.reset(); } else { - std::optional curr_feature = mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; + std::optional curr_feature = m_dragging ? m_curr_feature : + mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; + if (m_curr_feature != curr_feature || (curr_feature.has_value() && curr_feature->get_type() == Measure::SurfaceFeatureType::Circle && (m_curr_feature != curr_feature || m_last_inv_zoom != inv_zoom))) { m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); From 543950bf4bc3dcead2696a555cbe4430226da6dc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 09:13:28 +0100 Subject: [PATCH 70/99] Gizmo Measure - Use [Delete] key in place of Shift+Right mouse to restart selection --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 13 ++++++------- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 77d816aa76..2440b5f0a1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -401,12 +401,6 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) if ((m_mode != EMode::CenterSelection && mouse_event.CmdDown()) || (m_mode == EMode::CenterSelection && m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID)) { return false; } - - if (mouse_event.ShiftDown()) { - m_selected_features.reset(); - m_selection_raycasters.clear(); - m_parent.request_extra_frame(); - } } else if (mouse_event.Leaving()) m_mouse_left_down = false; @@ -477,6 +471,11 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po m_mode = control_down ? EMode::PointSelection : EMode::FeatureSelection; restore_scene_raycasters_state(); } + else if (action == SLAGizmoEventType::Delete) { + m_selected_features.reset(); + m_selection_raycasters.clear(); + m_parent.request_extra_frame(); + } return true; } @@ -1738,7 +1737,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit } if (m_selected_features.first.feature.has_value()) { - add_strings_row_to_table(*m_imgui, _u8L("Shift") + "+" + _u8L("Right mouse button"), ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Restart selection"), ImGui::GetStyleColorVec4(ImGuiCol_Text)); + add_strings_row_to_table(*m_imgui, _u8L("Delete"), ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Restart selection"), ImGui::GetStyleColorVec4(ImGuiCol_Text)); ++row_count; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 37d1d3de4c..c10741a14e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -554,7 +554,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt) case WXK_BACK: case WXK_DELETE: { - if ((m_current == SlaSupports || m_current == Hollow || m_current == Cut) && gizmo_event(SLAGizmoEventType::Delete)) + if ((m_current == SlaSupports || m_current == Hollow || m_current == Cut || m_current == Measure) && gizmo_event(SLAGizmoEventType::Delete)) processed = true; break; From a03528e55a402358540ad588b3772608ace0355f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 09:46:30 +0100 Subject: [PATCH 71/99] Gizmo Measure - Added [Restart selection] button to imgui dialog --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 2440b5f0a1..d01b74518d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1775,13 +1775,13 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ImGui::EndTable(); } - //if (m_selected_features.first.feature.has_value()) { - // if (m_imgui->button(_u8L("Restart"))) { - // m_selected_features.reset(); - // m_selection_raycasters.clear(); - // m_imgui->set_requires_extra_frame(); - // } - //} + m_imgui->disabled_begin(!m_selected_features.first.feature.has_value()); + if (m_imgui->button(_u8L("Restart selection"))) { + m_selected_features.reset(); + m_selection_raycasters.clear(); + m_imgui->set_requires_extra_frame(); + } + m_imgui->disabled_end(); auto add_measure_row_to_table = [this](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color) { ImGui::TableNextRow(); From ef018318bd8464b5b8a105adf7c8b7b141463900 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 10:26:53 +0100 Subject: [PATCH 72/99] Gizmo Measure - Clicking on 1st selected let second selected to be promoted as first selected --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 27 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index d01b74518d..0c8d83fdb6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -354,6 +354,10 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) else { if (!m_selected_features.second.feature.has_value()) m_selected_features.first.reset(); + else { + m_selected_features.first = m_selected_features.second; + m_selected_features.second.reset(); + } } } else { @@ -853,7 +857,7 @@ void GLGizmoMeasure::on_render() }; auto hover_selection_color = [this]() { - return !m_selected_features.first.feature.has_value() ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; + return (!m_selected_features.first.feature.has_value() || *m_curr_feature == *m_selected_features.first.feature) ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; }; auto hovering_color = [this, hover_selection_color, &selection]() { @@ -1693,14 +1697,27 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit std::string text; ColorRGBA color; if (m_selected_features.second.feature.has_value()) { - if (m_selected_features.second.feature == m_curr_feature && m_mode == EMode::FeatureSelection) + if (m_selected_features.first.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { text = _u8L("Unselect feature"); - else if (m_hover_id == SELECTION_2_ID) + color = SELECTED_1ST_COLOR; + } + else if (m_selected_features.second.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { + text = _u8L("Unselect feature"); + color = SELECTED_2ND_COLOR; + } + else if (m_hover_id == SELECTION_1_ID) { text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); - else + color = SELECTED_1ST_COLOR; + } + else if (m_hover_id == SELECTION_2_ID) { + text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); + color = SELECTED_2ND_COLOR; + } + else { text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : (m_mode == EMode::CenterSelection) ? _u8L("Select center") : _u8L("Select feature"); - color = SELECTED_2ND_COLOR; + color = SELECTED_2ND_COLOR; + } } else { if (m_selected_features.first.feature.has_value()) { From 38d2e0605a405c703c5a671aad284a9077a966b3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 11:20:14 +0100 Subject: [PATCH 73/99] Gizmo Measure - Handling of [ESC] key When two features are selected -> unselected second feature When one feature is selected -> unselect first feature When no feature is selected -> close gizmo --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 31 ++++++++++++++++++++++- src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 5 +++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 0c8d83fdb6..30602b1d49 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -480,6 +480,16 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po m_selection_raycasters.clear(); m_parent.request_extra_frame(); } + else if (action == SLAGizmoEventType::Escape) { + if (!m_selected_features.first.feature.has_value()) + return false; + else { + if (m_selected_features.second.feature.has_value()) + m_selected_features.second.feature.reset(); + else + m_selected_features.first.feature.reset(); + } + } return true; } @@ -1758,8 +1768,27 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ++row_count; } + if (m_selected_features.first.feature.has_value() || m_selected_features.second.feature.has_value()) { + add_row_to_table( + [this]() { + m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Esc")); + }, + [this]() { + m_imgui->text_colored(ImGui::GetStyleColorVec4(ImGuiCol_Text), _u8L("Unselect")); + ImGui::SameLine(); + const ImVec2 pos = ImGui::GetCursorScreenPos(); + const float rect_size = ImGui::GetTextLineHeight(); + const ColorRGBA color = m_selected_features.second.feature.has_value() ? SELECTED_2ND_COLOR : SELECTED_1ST_COLOR; + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + rect_size, pos.y + rect_size), ImGuiWrapper::to_ImU32(color)); + ImGui::Dummy(ImVec2(rect_size, rect_size)); + } + ); + + ++row_count; + } + // add dummy rows to keep dialog size fixed - for (unsigned int i = row_count; i < 4; ++i) { + for (unsigned int i = row_count; i < 5; ++i) { add_strings_row_to_table(*m_imgui, " ", ImGuiWrapper::COL_ORANGE_LIGHT, " ", ImGui::GetStyleColorVec4(ImGuiCol_Text)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 3878c6b25a..c1b605726c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -29,6 +29,7 @@ enum class SLAGizmoEventType : unsigned char { ShiftDown, ShiftUp, AltUp, + Escape, ApplyChanges, DiscardChanges, AutomaticGeneration, diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index c10741a14e..c68a510276 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -526,7 +526,10 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt) case WXK_ESCAPE: { if (m_current != Undefined) { - if ((m_current != SlaSupports) || !gizmo_event(SLAGizmoEventType::DiscardChanges)) + if (m_current == Measure && gizmo_event(SLAGizmoEventType::Escape)) { + // do nothing + } + else if (m_current != SlaSupports || !gizmo_event(SLAGizmoEventType::DiscardChanges)) reset_all_states(); processed = true; From ab5c81a2ef0cac6d688f1b660e76324637ab75ef Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 12:01:22 +0100 Subject: [PATCH 74/99] Gizmo Measure - Fixed point color and hint in dialog when adding a point on a selected feature --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 30602b1d49..29475105df 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -867,7 +867,9 @@ void GLGizmoMeasure::on_render() }; auto hover_selection_color = [this]() { - return (!m_selected_features.first.feature.has_value() || *m_curr_feature == *m_selected_features.first.feature) ? SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; + return ((m_mode == EMode::PointSelection && !m_selected_features.first.feature.has_value()) || + (m_mode != EMode::PointSelection && (!m_selected_features.first.feature.has_value() || *m_curr_feature == *m_selected_features.first.feature))) ? + SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; }; auto hovering_color = [this, hover_selection_color, &selection]() { @@ -1731,11 +1733,14 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit } else { if (m_selected_features.first.feature.has_value()) { - if (m_selected_features.first.feature == m_curr_feature) + if (m_selected_features.first.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { text = _u8L("Unselect feature"); - else if (m_hover_id == SELECTION_1_ID) + color = SELECTED_1ST_COLOR; + } + else if (m_hover_id == SELECTION_1_ID) { text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); - color = SELECTED_1ST_COLOR; + color = SELECTED_1ST_COLOR; + } } if (text.empty()) { text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : From df266798a63d94ee0fc2853b398edee4e3fce330 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 21 Nov 2022 14:44:31 +0100 Subject: [PATCH 75/99] Fixed crash when opening Measure Gizmo after slicing in SLA mode --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 29475105df..6f398d111b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -968,7 +968,7 @@ void GLGizmoMeasure::update_if_needed() // continue; TriangleMesh volume_mesh = vol.volume->mesh(); - volume_mesh.transform(vol.instance->get_transformation().get_matrix() * vol.volume->get_transformation().get_matrix()); + volume_mesh.transform(vol.world_trafo); composite_mesh.merge(volume_mesh); } @@ -987,10 +987,17 @@ void GLGizmoMeasure::update_if_needed() volumes_cache.reserve(idxs.size()); for (unsigned int idx : idxs) { const GLVolume* v = selection.get_volume(idx); + const int volume_idx = v->volume_idx(); + if (volume_idx < 0) + continue; + const ModelObject* obj = selection.get_model()->objects[v->object_idx()]; const ModelInstance* inst = obj->instances[v->instance_idx()]; - const ModelVolume* vol = obj->volumes[v->volume_idx()]; - const VolumeCacheItem item = { obj, inst, vol, inst->get_matrix() * vol->get_matrix() }; + const ModelVolume* vol = obj->volumes[volume_idx]; + const VolumeCacheItem item = { + obj, inst, vol, + Geometry::translation_transform(selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) * inst->get_matrix() * vol->get_matrix() + }; volumes_cache.emplace_back(item); } From cc0901228beecaa3a3187a57b5d3d58737bd4fa8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 22 Nov 2022 08:34:12 +0100 Subject: [PATCH 76/99] Gizmo measure - Fixed dimensioning after scaling a part of a multipart object --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 6f398d111b..8e32e7e3a5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1174,16 +1174,14 @@ void GLGizmoMeasure::render_dimensioning() Vec3d new_pivot; Transform3d scale_matrix; - TrafoData(double ratio, const Vec3d& pivot) { + TrafoData(double ratio, const Vec3d& old_pivot, const Vec3d& new_pivot) { this->ratio = ratio; this->scale_matrix = Geometry::scale_transform(ratio); - this->old_pivot = pivot; - this->new_pivot = { pivot.x(), pivot.y(), (this->scale_matrix * pivot).z() }; + this->old_pivot = old_pivot; + this->new_pivot = new_pivot; } - Vec3d transform(const Vec3d& point) const { - return this->scale_matrix * (point - this->old_pivot) + this->new_pivot; - } + Vec3d transform(const Vec3d& point) const { return this->scale_matrix * (point - this->old_pivot) + this->new_pivot; } }; auto scale_feature = [](Measure::SurfaceFeature& feature, const TrafoData& trafo_data) { @@ -1218,22 +1216,26 @@ void GLGizmoMeasure::render_dimensioning() } }; - const TrafoData trafo_data(ratio, m_parent.get_selection().get_bounding_box().center()); - scale_feature(*m_selected_features.first.feature, trafo_data); - scale_feature(*m_selected_features.second.feature, trafo_data); - + // apply scale TransformationType type; type.set_world(); type.set_relative(); type.set_joint(); - // apply scale + // scale selection Selection& selection = m_parent.get_selection(); + const Vec3d old_center = selection.get_bounding_box().center(); selection.setup_cache(); selection.scale(ratio * Vec3d::Ones(), type); wxGetApp().plater()->canvas3D()->do_scale(""); // avoid storing another snapshot wxGetApp().obj_manipul()->set_dirty(); + // scale dimensioning + const Vec3d new_center = selection.get_bounding_box().center(); + const TrafoData trafo_data(ratio, old_center, new_center); + scale_feature(*m_selected_features.first.feature, trafo_data); + scale_feature(*m_selected_features.second.feature, trafo_data); + // update measure on next call to data_changed() m_pending_scale = true; }; From 87fb1604d88e65b25260a5bdb82f8bcc5c0c86b1 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 22 Nov 2022 12:36:51 +0100 Subject: [PATCH 77/99] Gizmo measure - Fixed incorrect point on feature detection --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 8e32e7e3a5..f4c85a1b54 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -666,7 +666,7 @@ void GLGizmoMeasure::on_render() return trafo * p.cast(); } } - return Vec3d::Zero(); + return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); }; if (m_curr_feature.has_value()) { @@ -683,8 +683,11 @@ void GLGizmoMeasure::on_render() const std::optional extra = m_curr_feature->get_extra_point(); if (extra.has_value() && m_hover_id == POINT_ID) m_curr_point_on_feature_position = *extra; - else - m_curr_point_on_feature_position = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); + else { + const Vec3d pos = position_on_feature(EDGE_ID, camera, [](const Vec3f& v) { return Vec3f(0.0f, 0.0f, v.z()); }); + if (!pos.isApprox(Vec3d(DBL_MAX, DBL_MAX, DBL_MAX))) + m_curr_point_on_feature_position = pos; + } break; } case Measure::SurfaceFeatureType::Plane: @@ -715,6 +718,7 @@ void GLGizmoMeasure::on_render() } } else { + m_curr_point_on_feature_position.reset(); if (m_curr_feature.has_value() && m_curr_feature->get_type() == Measure::SurfaceFeatureType::Circle) { if (update_circle()) { m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); From 36b4a149a48e4f1a3922572656a13c884dc1c5ad Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 22 Nov 2022 13:13:25 +0100 Subject: [PATCH 78/99] Gizmo measure - Fixed calculation of angle edge-plane --- src/libslic3r/Measure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 8213f9778d..9105d65c85 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -34,7 +34,7 @@ static std::array orthonormal_basis(const Vec3d& v) std::array ret; ret[2] = v.normalized(); int index; - ret[2].maxCoeff(&index); + ret[2].cwiseAbs().maxCoeff(&index); switch (index) { case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; } From 786eb4dc530377e67ec62c76b8808c494581475b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 22 Nov 2022 14:40:35 +0100 Subject: [PATCH 79/99] Follow-up of fdc9c73340060cea7d8335e1211836681e18cae0 - Alternate implementation of 'When panning/rotating the scene, do not select the hovered feature, if any' --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index f4c85a1b54..05374124e6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -254,7 +254,6 @@ GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filen bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) { m_mouse_pos = { double(mouse_event.GetX()), double(mouse_event.GetY()) }; - m_dragging = false; if (mouse_event.Moving()) { // only for sure @@ -262,8 +261,6 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) return false; } else if (mouse_event.Dragging()) { - m_dragging = true; - // Enable/Disable panning/rotating the 3D scene // Ctrl is pressed or the mouse is not hovering a selected volume bool unlock_dragging = mouse_event.CmdDown() || (m_hover_id == -1 && !m_parent.get_selection().contains_volume(m_parent.get_first_hover_volume_idx())); @@ -594,7 +591,7 @@ void GLGizmoMeasure::on_render() m_curr_point_on_feature_position.reset(); } else { - std::optional curr_feature = m_dragging ? m_curr_feature : + std::optional curr_feature = wxGetMouseState().LeftIsDown() ? m_curr_feature : mouse_on_object ? m_measuring->get_feature(model_facet_idx, position_on_model.cast()) : std::nullopt; if (m_curr_feature != curr_feature || From dedaa7b49b164717943729f35c5d6f6b9009635c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Nov 2022 08:24:08 +0100 Subject: [PATCH 80/99] Gizmo measure - Fixed color of hovered features when part of the object is outside the printbed --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 05374124e6..fa8240f8d6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -752,7 +752,7 @@ void GLGizmoMeasure::on_render() }; auto set_emission_uniform = [this, shader](const ColorRGBA& color, bool hover) { - shader->set_uniform("emission_factor", (color == m_parent.get_selection().get_first_volume()->render_color) ? 0.0f : + shader->set_uniform("emission_factor", (color == GLVolume::SELECTED_COLOR) ? 0.0f : hover ? 0.5f : 0.25f); }; @@ -874,7 +874,7 @@ void GLGizmoMeasure::on_render() }; auto hovering_color = [this, hover_selection_color, &selection]() { - return (m_mode == EMode::PointSelection) ? selection.get_first_volume()->render_color : hover_selection_color(); + return (m_mode == EMode::PointSelection) ? GLVolume::SELECTED_COLOR : hover_selection_color(); }; if (m_curr_feature.has_value()) { From 946bbd285a54ecd389a7f2ef859ca4f82ce9808b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Nov 2022 09:10:56 +0100 Subject: [PATCH 81/99] Fixed warnings --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index fa8240f8d6..89e6b63ef1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -751,7 +751,7 @@ void GLGizmoMeasure::on_render() shader->set_uniform("view_normal_matrix", view_normal_matrix); }; - auto set_emission_uniform = [this, shader](const ColorRGBA& color, bool hover) { + auto set_emission_uniform = [shader](const ColorRGBA& color, bool hover) { shader->set_uniform("emission_factor", (color == GLVolume::SELECTED_COLOR) ? 0.0f : hover ? 0.5f : 0.25f); }; @@ -873,7 +873,7 @@ void GLGizmoMeasure::on_render() SELECTED_1ST_COLOR : SELECTED_2ND_COLOR; }; - auto hovering_color = [this, hover_selection_color, &selection]() { + auto hovering_color = [this, hover_selection_color]() { return (m_mode == EMode::PointSelection) ? GLVolume::SELECTED_COLOR : hover_selection_color(); }; From 2b155d593292c78f51e69118fa6fc79cc119cdbc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Nov 2022 12:03:36 +0100 Subject: [PATCH 82/99] Gizmo measure - Hide SLA supports and pad when opening the gizmo --- src/slic3r/GUI/GLCanvas3D.cpp | 19 +++++++++++++++++-- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 5 +++++ src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 991bbead28..345beb4434 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1346,11 +1346,26 @@ void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObje m_render_sla_auxiliaries = visible; +#if ENABLE_RAYCAST_PICKING + std::vector>* raycasters = get_raycasters_for_picking(SceneRaycaster::EType::Volume); +#endif // ENABLE_RAYCAST_PICKING + for (GLVolume* vol : m_volumes.volumes) { +#if ENABLE_RAYCAST_PICKING if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) - && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) - && vol->composite_id.volume_id < 0) + && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) + && vol->composite_id.volume_id < 0) { vol->is_active = visible; + auto it = std::find_if(raycasters->begin(), raycasters->end(), [vol](std::shared_ptr item) { return item->get_raycaster() == vol->mesh_raycaster.get(); }); + if (it != raycasters->end()) + (*it)->set_active(vol->is_active); + } +#else + if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) + && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) + && vol->composite_id.volume_id < 0) + vol->is_active = visible; +#endif // ENABLE_RAYCAST_PICKING } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 1ce118d71d..51ea56c821 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -900,6 +900,11 @@ RENDER_AGAIN: bool show_sups = m_c->instances_hider()->are_supports_shown(); if (m_imgui->checkbox(m_desc["show_supports"], show_sups)) { m_c->instances_hider()->show_supports(show_sups); +#if ENABLE_RAYCAST_PICKING + if (show_sups) + // ensure supports and pad are disabled from picking even when they are visible + set_sla_auxiliary_volumes_picking_state(false); +#endif // ENABLE_RAYCAST_PICKING force_refresh = true; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 89e6b63ef1..2de29087b8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -411,6 +411,8 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) void GLGizmoMeasure::data_changed() { + m_parent.toggle_sla_auxiliaries_visibility(false, nullptr, -1); + update_if_needed(); m_last_inv_zoom = 0.0f; @@ -500,6 +502,7 @@ bool GLGizmoMeasure::on_init() void GLGizmoMeasure::on_set_state() { if (m_state == Off) { + m_parent.toggle_sla_auxiliaries_visibility(true, nullptr, -1); m_ctrl_kar_filter.reset_count(); m_shift_kar_filter.reset_count(); m_curr_feature.reset(); From 3bdd548358735fa75987a6560234470525b649b4 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Nov 2022 12:37:54 +0100 Subject: [PATCH 83/99] Gizmo measure - Undo/Redo related fix --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 9699d73cc8..1672e8b74e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -159,6 +159,11 @@ public: bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); + bool wants_enter_leave_snapshots() const override { return true; } + std::string get_gizmo_entering_text() const override { return _u8L("Entering Measure gizmo"); } + std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Measure gizmo"); } + std::string get_action_snapshot_name() override { return _u8L("Measure gizmo editing"); } + protected: bool on_init() override; std::string on_get_name() const override; From d4ad4aff01598d60ce0d9e3114e47cd704083b4d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 22 Nov 2022 09:49:10 +0100 Subject: [PATCH 84/99] Measurement: Fixed and refactored circle detection: - first/last segment of a circular segment was sometimes separated - circles were sometimes shown where they shouldn't be --- src/libslic3r/Measure.cpp | 236 +++++++++++++++++++------------------- 1 file changed, 120 insertions(+), 116 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 9105d65c85..a9cea06bdd 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -14,17 +14,17 @@ namespace Measure { constexpr double feature_hover_limit = 0.5; // how close to a feature the mouse must be to highlight it -static std::pair get_center_and_radius(const std::vector& border, int start_idx, int end_idx, const Transform3d& trafo) +static std::pair get_center_and_radius(const std::vector& points, const Transform3d& trafo) { - Vec2ds pts; + Vec2ds out; double z = 0.; - for (int i=start_idx; i<=end_idx; ++i) { - Vec3d pt_transformed = trafo * border[i]; + for (const Vec3d pt : points) { + Vec3d pt_transformed = trafo * pt; z = pt_transformed.z(); - pts.emplace_back(pt_transformed.x(), pt_transformed.y()); + out.emplace_back(pt_transformed.x(), pt_transformed.y()); } - auto circle = Geometry::circle_ransac(pts, 20); // FIXME: iterations? + auto circle = Geometry::circle_ransac(out, 20); // FIXME: iterations? return std::make_pair(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius); } @@ -216,6 +216,7 @@ void MeasuringImpl::update_planes() m_planes[plane_id].borders.pop_back(); else { assert(last_border.front() == last_border.back()); + last_border.pop_back(); } } } @@ -233,6 +234,9 @@ void MeasuringImpl::update_planes() void MeasuringImpl::extract_features() { + auto are_angles_same = [](double a, double b) { return Slic3r::is_approx(a,b); }; + auto are_lengths_same = [](double a, double b) { return Slic3r::is_approx(a,b); }; + std::vector angles; std::vector lengths; @@ -246,152 +250,152 @@ void MeasuringImpl::extract_features() q.setFromTwoVectors(plane.normal, Vec3d::UnitZ()); Transform3d trafo = Transform3d::Identity(); trafo.rotate(q); - + for (const std::vector& border : plane.borders) { if (border.size() <= 1) continue; - assert(border.front() == border.back()); - int start_idx = -1; - std::vector edges; + // Given an idx into border, return the index that is idx+offset position, + // while taking into account the need for warp-around and the fact that + // the first and last point are the same. + auto offset_to_index = [border_size = int(border.size())](int idx, int offset) -> int { + assert(std::abs(offset) < border_size); + int out = idx+offset; + if (out >= border_size) + out = out - border_size; + else if (out < 0) + out = border_size + out; + + return out; + }; // First calculate angles at all the vertices. angles.clear(); lengths.clear(); - for (int i=0; i M_PI) angle = 2*M_PI - angle; angles.push_back(angle); lengths.push_back(v2.norm()); + if (first_different_angle_idx == 0 && angles.size() > 1) { + if (! are_angles_same(angles.back(), angles[angles.size()-2])) + first_different_angle_idx = angles.size()-1; + } } assert(border.size() == angles.size()); assert(border.size() == lengths.size()); - // First go around the border and pick what might be circular segments. // Save pair of indices to where such potential segments start and end. // Also remember the length of these segments. + int start_idx = -1; bool circle = false; + bool first_iter = true; std::vector circles; + std::vector edges; std::vector> circles_idxs; - std::vector circles_lengths; - for (int i=1; i<(int)angles.size(); ++i) { - if (Slic3r::is_approx(lengths[i], lengths[i-1]) - && Slic3r::is_approx(angles[i], angles[i-1]) - && i != (int)angles.size()-1 ) { + //std::vector circles_lengths; + std::vector single_circle; // could be in loop-scope, but reallocations + double single_circle_length = 0.; + int first_pt_idx = offset_to_index(first_different_angle_idx, 1); + int i = first_pt_idx; + while (i != first_pt_idx || first_iter) { + if (are_angles_same(angles[i], angles[offset_to_index(i,-1)]) + && i != offset_to_index(first_pt_idx, -1) // not the last point + && i != start_idx ) { // circle if (! circle) { circle = true; - start_idx = std::max(0, i-2); + single_circle.clear(); + single_circle_length = 0.; + start_idx = offset_to_index(i, -2); + single_circle = { border[start_idx], border[offset_to_index(start_idx,1)] }; + single_circle_length += lengths[offset_to_index(i, -1)]; } + single_circle.emplace_back(border[i]); + single_circle_length += lengths[i]; } else { - if (circle) { - const auto& [center, radius] = get_center_and_radius(border, start_idx, i, trafo); - // Add the circle and remember indices into borders. - circles_idxs.emplace_back(start_idx, i); - circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius)); - circles_lengths.emplace_back(std::accumulate(lengths.begin() + start_idx + 1, lengths.begin() + i + 1, 0.)); - circle = false; - } - } - } + if (circle && single_circle.size() >= 5) { // Less than 5 vertices? Not a circle. + single_circle.emplace_back(border[i]); + single_circle_length += lengths[i]; - // At this point we might need to merge the first and last segment, if the starting - // point happened to be inside the segment. The discrimination of too small segments - // will follow, so we need a complete picture before that. - if (circles_idxs.size() > 1 - && circles_idxs.back().second == (int)angles.size()-1 - && circles_idxs.front().first == 0) { - // Possibly the same circle. Check that the angle and length criterion holds along the combined segment. - bool same = true; - double last_len = -1.; - double last_angle = 0.; - for (int i=circles_idxs.back().first + 1; i != circles_idxs.front().second; ++i) { - if (i == (int)angles.size()) - i = 1; - if (last_len == -1.) { - last_len = lengths[i]; - last_angle = angles[i]; - } else { - if (! Slic3r::is_approx(lengths[i], last_len) || ! Slic3r::is_approx(angles[i], last_angle)) { - same = false; - break; + bool accept_circle = true; + { + // Check that lengths of internal (!!!) edges match. + int j = offset_to_index(start_idx, 3); + while (j != i) { + if (! are_lengths_same(lengths[offset_to_index(j,-1)], lengths[j])) { + accept_circle = false; + break; + } + j = offset_to_index(j, 1); + } + } + + if (accept_circle) { + const auto& [center, radius] = get_center_and_radius(single_circle, trafo); + + // Check that the fit went well. The tolerance is high, only to + // reject complete failures. + for (const Vec3d& pt : single_circle) { + if (std::abs((pt - center).norm() - radius) > 0.5) { + accept_circle = false; + break; + } + } + + // If the segment subtends less than 90 degrees, throw it away. + accept_circle &= single_circle_length / radius > 0.9*M_PI/2.; + + // If this is all-around and 5 to 8 vertices, consider it a polygon. + bool is_polygon = start_idx == i && single_circle.size() <= 9 && single_circle.size() >= 6; + + if (accept_circle) { + // Add the circle and remember indices into borders. + circles_idxs.emplace_back(start_idx, i); + if (is_polygon) { + for (int j=0; j<=i; ++j) // No wrap-around handling needed here. + edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, + border[j==0 ? border.size()-1 : j-1], border[j], + std::make_optional(center))); + } + else + circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius)); + } } } + circle = false; } - if (same) { - // This seems to really be the same circle. Better apply ransac again. The parts can be small and inexact. - std::vector points(border.begin() + circles_idxs.back().first, border.end()); - points.insert(points.end(), border.begin(), border.begin() + circles_idxs.front().second+1); - auto [c, radius] = get_center_and_radius(points, 0, points.size()-1, trafo); - - // Now replace the first circle with the combined one, remove the last circle. - // First index of the first circle is saved negative - we are going to pick edges - // from the border later, we will need to know where the merged in segment was. - // The sign simplifies the algorithm that picks the remaining edges - see below. - circles.front() = SurfaceFeature(SurfaceFeatureType::Circle, c, plane.normal, std::nullopt, radius); - circles_idxs.front().first = - circles_idxs.back().first; - circles_lengths.front() += circles_lengths.back(); - circles.pop_back(); - circles_idxs.pop_back(); - circles_lengths.pop_back(); - } - } - - // Now throw away all circles that subtend less than 90 deg. - assert(circles.size() == circles_lengths.size()); - for (int i=0; i(circles[i].get_circle()); - if (circles_lengths[i] / r < 0.9*M_PI/2.) { - circles_lengths.erase(circles_lengths.begin() + i); - circles.erase(circles.begin() + i); - circles_idxs.erase(circles_idxs.begin() + i); - --i; - } + // Take care of the wrap around. + first_iter = false; + i = offset_to_index(i, 1); } - circles_lengths.clear(); // no longer needed, make it obvious - - // Anything under 5 vertices shall not be considered a circle. - assert(circles_idxs.size() == circles.size()); - for (int i=int(circles_idxs.size())-1; i>=0; --i) { - const auto& [start, end] = circles_idxs[i]; - int N = start >= 0 - ? end - start + (start == 0 && end == (int)border.size()-1 ? 0 : 1) // last point is the same as first - : end + (border.size() + start); - if (N < 5) { - circles.erase(circles.begin() + i); - circles_idxs.erase(circles_idxs.begin() + i); - } else if (N <= 8 && start == 0 && end == (int)border.size()-1) { - // This is a regular 5-8 polygon. Add the edges as edges with a special - // point and remove the circle. Leave the indices in circles_idxs, so - // the edges are not picked up again later. - const Vec3d center = std::get<0>(circles[i].get_circle()); - for (int j=1; j<=end; ++j) - edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, - border[j - 1], border[j], std::make_optional(center))); - circles.erase(circles.begin() + i); - } - } - // We have the circles. Now go around again and pick edges, while jumping over circles. - // If the first index of the first circle is negative, it means that it was merged - // with a segment that was originally at the back and is no longer there. Ressurect - // its pair of indices so that edges are not picked again. - if (! circles_idxs.empty() && circles_idxs.front().first < 0) - circles_idxs.emplace_back(-circles_idxs.front().first, int(border.size())); - int cidx = 0; // index of next circle to jump over - for (int i=1; i (int)circles_idxs[cidx].first) - i = circles_idxs[cidx++].second; - else - edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[i - 1], border[i])); + if (circles_idxs.empty()) { + // Just add all edges. + for (int i=1; i Date: Fri, 25 Nov 2022 13:45:23 +0100 Subject: [PATCH 85/99] Measurement: prevent ending up in an infinite loop with broken models --- src/libslic3r/Measure.cpp | 16 ++++++++++++++-- src/libslic3r/SurfaceMesh.hpp | 9 +++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index a9cea06bdd..37bf68e83d 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -189,10 +189,16 @@ void MeasuringImpl::update_planes() he = sm.next_around_target(he); if (he.is_invalid()) goto PLANE_FAILURE; + + // For broken meshes, the iteration might never get back to he_orig. + // Remember all halfedges we saw to break out of such infinite loops. + boost::container::small_vector he_seen; + while ( (int)m_face_to_plane[sm.face(he)] == plane_id && he != he_orig) { + he_seen.emplace_back(he); he = sm.next_around_target(he); - if (he.is_invalid()) - goto PLANE_FAILURE; + if (he.is_invalid() || std::find(he_seen.begin(), he_seen.end(), he) != he_seen.end()) + goto PLANE_FAILURE; } he = sm.opposite(he); if (he.is_invalid()) @@ -210,6 +216,12 @@ void MeasuringImpl::update_planes() visited[face_it - facets.begin()][he.side()] = true; last_border.emplace_back(sm.point(sm.source(he)).cast()); + + // In case of broken meshes, this loop might be infinite. Break + // out in case it is clearly going bad. + if (last_border.size() > 3*facets.size()) + goto PLANE_FAILURE; + } while (he != he_start); if (last_border.size() == 1) diff --git a/src/libslic3r/SurfaceMesh.hpp b/src/libslic3r/SurfaceMesh.hpp index 9e547eec49..93eb9fdaa6 100644 --- a/src/libslic3r/SurfaceMesh.hpp +++ b/src/libslic3r/SurfaceMesh.hpp @@ -4,6 +4,8 @@ #include #include +#include "boost/container/small_vector.hpp" + namespace Slic3r { class TriangleMesh; @@ -115,11 +117,18 @@ public: size_t degree(Vertex_index v) const { + // In case the mesh is broken badly, the loop might end up to be infinite, + // never getting back to the first halfedge. Remember list of all half-edges + // and trip if any is encountered for the second time. Halfedge_index h_first = halfedge(v); + boost::container::small_vector he_visited; Halfedge_index h = next_around_target(h_first); size_t degree = 2; while (! h.is_invalid() && h != h_first) { + he_visited.emplace_back(h); h = next_around_target(h); + if (std::find(he_visited.begin(), he_visited.end(), h) == he_visited.end()) + return 0; ++degree; } return h.is_invalid() ? 0 : degree - 1; From 8ef55ff82eabe498e0f08fe1cd7f02afedda20de Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 29 Nov 2022 11:13:09 +0100 Subject: [PATCH 86/99] Tech ENABLE_RAYCAST_PICKING_DEBUG - Extended data shown into debug imgui dialog --- src/slic3r/GUI/GLCanvas3D.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 345beb4434..9f2e7c0dad 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5542,12 +5542,17 @@ void GLCanvas3D::_picking_pass() default: { break; } } - auto add_strings_row_to_table = [&imgui](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color) { + auto add_strings_row_to_table = [&imgui](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color, + const std::string& col_3 = "", const ImVec4& col_3_color = ImGui::GetStyleColorVec4(ImGuiCol_Text)) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); imgui.text_colored(col_1_color, col_1.c_str()); ImGui::TableSetColumnIndex(1); imgui.text_colored(col_2_color, col_2.c_str()); + if (!col_3.empty()) { + ImGui::TableSetColumnIndex(2); + imgui.text_colored(col_3_color, col_3.c_str()); + } }; char buf[1024]; @@ -5576,6 +5581,21 @@ void GLCanvas3D::_picking_pass() add_strings_row_to_table("Gizmo elements", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text)); ImGui::EndTable(); } + + std::vector>* gizmo_raycasters = m_scene_raycaster.get_raycasters(SceneRaycaster::EType::Gizmo); + if (gizmo_raycasters != nullptr && !gizmo_raycasters->empty()) { + ImGui::Separator(); + imgui.text("Gizmo raycasters IDs:"); + if (ImGui::BeginTable("GizmoRaycasters", 3)) { + for (size_t i = 0; i < gizmo_raycasters->size(); ++i) { + add_strings_row_to_table(std::to_string(i), ImGuiWrapper::COL_ORANGE_LIGHT, + std::to_string(SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, (*gizmo_raycasters)[i]->get_id())), ImGui::GetStyleColorVec4(ImGuiCol_Text), + to_string(Geometry::Transformation((*gizmo_raycasters)[i]->get_transform()).get_offset()), ImGui::GetStyleColorVec4(ImGuiCol_Text)); + } + ImGui::EndTable(); + } + } + imgui.end(); #endif // ENABLE_RAYCAST_PICKING_DEBUG } From b45ae31af3be42f5b04dd0c6ea87cb0db505c044 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 11:58:02 +0100 Subject: [PATCH 87/99] Gizmo measure - Modified circle and edge with extra point selection Fixed conflicts during rebase to master --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 510 ++++++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 18 +- 2 files changed, 320 insertions(+), 208 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 2de29087b8..43d55addda 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -20,15 +20,16 @@ namespace Slic3r { namespace GUI { -static const Slic3r::ColorRGBA SELECTED_1ST_COLOR = { 0.25f, 0.75f, 0.75f, 1.0f }; -static const Slic3r::ColorRGBA SELECTED_2ND_COLOR = { 0.75f, 0.25f, 0.75f, 1.0f }; +static const Slic3r::ColorRGBA SELECTED_1ST_COLOR = { 0.25f, 0.75f, 0.75f, 1.0f }; +static const Slic3r::ColorRGBA SELECTED_2ND_COLOR = { 0.75f, 0.25f, 0.75f, 1.0f }; +static const Slic3r::ColorRGBA NEUTRAL_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f }; static const int POINT_ID = 100; static const int EDGE_ID = 200; static const int CIRCLE_ID = 300; static const int PLANE_ID = 400; -static const int SELECTION_1_ID = 501; -static const int SELECTION_2_ID = 502; +static const int SEL_SPHERE_1_ID = 501; +static const int SEL_SPHERE_2_ID = 502; static const float TRIANGLE_BASE = 10.0f; static const float TRIANGLE_HEIGHT = TRIANGLE_BASE * 1.618033f; @@ -164,6 +165,41 @@ static GLModel::Geometry init_torus_data(unsigned int primary_resolution, unsign return data; } +static bool is_feature_with_center(const Measure::SurfaceFeature& feature) +{ + const Measure::SurfaceFeatureType type = feature.get_type(); + return (type == Measure::SurfaceFeatureType::Circle || (type == Measure::SurfaceFeatureType::Edge && feature.get_extra_point().has_value())); +} + +static Vec3d get_feature_offset(const Measure::SurfaceFeature& feature) +{ + Vec3d ret; + switch (feature.get_type()) + { + case Measure::SurfaceFeatureType::Circle: + { + const auto [center, radius, normal] = feature.get_circle(); + ret = center; + break; + } + case Measure::SurfaceFeatureType::Edge: + { + std::optional p = feature.get_extra_point(); + assert(p.has_value()); + ret = *p; + break; + } + case Measure::SurfaceFeatureType::Point: + { + ret = feature.get_point(); + break; + } + default: { assert(false); } + } + + return ret; +} + class TransformHelper { struct Cache @@ -265,109 +301,125 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) // Ctrl is pressed or the mouse is not hovering a selected volume bool unlock_dragging = mouse_event.CmdDown() || (m_hover_id == -1 && !m_parent.get_selection().contains_volume(m_parent.get_first_hover_volume_idx())); // mode is not center selection or mouse is not hovering a center - unlock_dragging &= !mouse_event.ShiftDown() || (m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID && m_hover_id != POINT_ID); + unlock_dragging &= !mouse_event.ShiftDown() || (m_hover_id != SEL_SPHERE_1_ID && m_hover_id != SEL_SPHERE_2_ID && m_hover_id != POINT_ID); return !unlock_dragging; } else if (mouse_event.LeftDown()) { // let the event pass through to allow panning/rotating the 3D scene - if ((m_mode != EMode::CenterSelection && mouse_event.CmdDown()) || - (m_mode == EMode::CenterSelection && m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID && m_hover_id != POINT_ID)) { + if (mouse_event.CmdDown()) return false; - } if (m_hover_id != -1) { SelectedFeatures selected_features_old = m_selected_features; m_mouse_left_down = true; - auto item_from_feature = [this]() { + auto detect_current_item = [this]() { SelectedFeatures::Item item; - if (m_hover_id == SELECTION_1_ID && m_selected_features.first.feature.has_value()) - item = m_selected_features.first; - else if (m_hover_id == SELECTION_2_ID && m_selected_features.second.feature.has_value()) - item = m_selected_features.second; + if (m_hover_id == SEL_SPHERE_1_ID) { + if (m_selected_features.first.is_center) + // mouse is hovering over a selected center + item = { true, m_selected_features.first.source, { Measure::SurfaceFeature(get_feature_offset(*m_selected_features.first.source)) } }; + else if (is_feature_with_center(*m_selected_features.first.feature)) + // mouse is hovering over a unselected center + item = { true, m_selected_features.first.feature, { Measure::SurfaceFeature(get_feature_offset(*m_selected_features.first.feature)) } }; + else + // mouse is hovering over a point + item = m_selected_features.first; + } + else if (m_hover_id == SEL_SPHERE_2_ID) { + if (m_selected_features.second.is_center) + // mouse is hovering over a selected center + item = { true, m_selected_features.second.source, { Measure::SurfaceFeature(get_feature_offset(*m_selected_features.second.source)) } }; + else if (is_feature_with_center(*m_selected_features.second.feature)) + // mouse is hovering over a center + item = { true, m_selected_features.second.feature, { Measure::SurfaceFeature(get_feature_offset(*m_selected_features.second.feature)) } }; + else + // mouse is hovering over a point + item = m_selected_features.second; + } else { switch (m_mode) { - case EMode::FeatureSelection: - { - item = { surface_feature_type_as_string(m_curr_feature->get_type()), m_curr_feature }; - break; - } - case EMode::PointSelection: - { - item = { point_on_feature_type_as_string(m_curr_feature->get_type(), m_hover_id), Measure::SurfaceFeature(*m_curr_point_on_feature_position) }; - break; - } - case EMode::CenterSelection: - { - Vec3d position; - switch (m_curr_feature->get_type()) - { - case Measure::SurfaceFeatureType::Circle: - { - position = std::get<0>(m_curr_feature->get_circle()); - break; - } - case Measure::SurfaceFeatureType::Edge: - { - assert(m_curr_feature->get_extra_point().has_value()); - position = *m_curr_feature->get_extra_point(); - break; - } - default: { assert(false); break; } - } - - item = { center_on_feature_type_as_string(m_curr_feature->get_type()), Measure::SurfaceFeature(position) }; - break; - } + case EMode::FeatureSelection: { item = { false, m_curr_feature, m_curr_feature }; break; } + case EMode::PointSelection: { item = { false, m_curr_feature, Measure::SurfaceFeature(*m_curr_point_on_feature_position) }; break; } } } return item; }; - if (m_selected_features.first.feature.has_value()) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); - if (it != m_selection_raycasters.end()) - m_selection_raycasters.erase(it); - m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, SELECTION_2_ID); + auto requires_sphere_raycaster_for_picking = [this](const SelectedFeatures::Item& item) { + if (m_mode == EMode::PointSelection) + return true; + else if (m_mode == EMode::FeatureSelection) { + if (is_feature_with_center(*item.feature)) + return true; + } + return false; + }; - const SelectedFeatures::Item item = item_from_feature(); + if (m_selected_features.first.feature.has_value()) { + const SelectedFeatures::Item item = detect_current_item(); if (m_selected_features.first != item) { - if (m_selected_features.second == item) - m_selected_features.second.reset(); - else { - m_selected_features.second = item; - if (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) - m_selection_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SELECTION_2_ID, *m_sphere.mesh_raycaster)); - if (m_mode == EMode::CenterSelection) { - // Fake ctrl up event to exit the center selection mode - gizmo_event(SLAGizmoEventType::CtrlUp, Vec2d::Zero(), true, false, false); - // increase counter to avoid that keeping the ctrl key pressed triggers a ctrl down event - m_ctrl_kar_filter.increase_count(); + bool processed = false; + if (item.is_center) { + if (item.source == m_selected_features.first.feature) { + // switch 1st selection from feature to its center + m_selected_features.first = item; + processed = true; + } + else if (item.source == m_selected_features.second.feature) { + // switch 2nd selection from feature to its center + m_selected_features.second = item; + processed = true; + } + } + else if (is_feature_with_center(*item.feature)) { + if (m_selected_features.first.is_center && m_selected_features.first.source == item.feature) { + // switch 1st selection from center to its feature + m_selected_features.first = item; + processed = true; + } + else if (m_selected_features.second.is_center && m_selected_features.second.source == item.feature) { + // switch 2nd selection from center to its feature + m_selected_features.second = item; + processed = true; + } + } + + if (!processed) { + remove_selected_sphere_raycaster(SEL_SPHERE_2_ID); + if (m_selected_features.second == item) + // 2nd feature deselection + m_selected_features.second.reset(); + else { + // 2nd feature selection + m_selected_features.second = item; + if (requires_sphere_raycaster_for_picking(item)) + m_selected_sphere_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SEL_SPHERE_2_ID, *m_sphere.mesh_raycaster)); } } } else { - if (!m_selected_features.second.feature.has_value()) - m_selected_features.first.reset(); - else { + remove_selected_sphere_raycaster(SEL_SPHERE_1_ID); + if (m_selected_features.second.feature.has_value()) { + // promote 2nd feature to 1st feature + remove_selected_sphere_raycaster(SEL_SPHERE_2_ID); m_selected_features.first = m_selected_features.second; + if (requires_sphere_raycaster_for_picking(m_selected_features.first)) + m_selected_sphere_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SEL_SPHERE_1_ID, *m_sphere.mesh_raycaster)); m_selected_features.second.reset(); } + else + // 1st feature deselection + m_selected_features.first.reset(); } } else { - const SelectedFeatures::Item item = item_from_feature(); + // 1st feature selection + const SelectedFeatures::Item item = detect_current_item(); m_selected_features.first = item; - if (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) - m_selection_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SELECTION_1_ID, *m_sphere.mesh_raycaster)); - if (m_mode == EMode::CenterSelection) { - // Fake ctrl up event to exit the center selection mode - gizmo_event(SLAGizmoEventType::CtrlUp, Vec2d::Zero(), true, false, false); - // increase counter to avoid that keeping the ctrl key pressed triggers a ctrl down event - m_ctrl_kar_filter.increase_count(); - } + if (requires_sphere_raycaster_for_picking(item)) + m_selected_sphere_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SEL_SPHERE_1_ID, *m_sphere.mesh_raycaster)); } if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) @@ -399,9 +451,8 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) } else if (mouse_event.RightDown()) { // let the event pass through to allow panning/rotating the 3D scene - if ((m_mode != EMode::CenterSelection && mouse_event.CmdDown()) || (m_mode == EMode::CenterSelection && m_hover_id != SELECTION_1_ID && m_hover_id != SELECTION_2_ID)) { + if (mouse_event.CmdDown()) return false; - } } else if (mouse_event.Leaving()) m_mouse_left_down = false; @@ -423,7 +474,7 @@ void GLGizmoMeasure::data_changed() } else m_selected_features.reset(); - m_selection_raycasters.clear(); + m_selected_sphere_raycasters.clear(); m_editing_distance = false; m_is_editing_distance_first_frame = true; } @@ -450,7 +501,7 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po if (action == SLAGizmoEventType::ShiftDown) { if (m_shift_kar_filter.is_first()) { - m_mode = activate_center_selection(SLAGizmoEventType::ShiftDown) ? EMode::CenterSelection : EMode::PointSelection; + m_mode = EMode::PointSelection; disable_scene_raycasters(); } m_shift_kar_filter.increase_count(); @@ -460,33 +511,23 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po m_mode = EMode::FeatureSelection; restore_scene_raycasters_state(); } - else if (action == SLAGizmoEventType::CtrlDown) { - if (m_ctrl_kar_filter.is_first()) { - if (activate_center_selection(SLAGizmoEventType::CtrlDown)) { - m_mode = EMode::CenterSelection; - disable_scene_raycasters(); - } - } - m_ctrl_kar_filter.increase_count(); - } - else if (action == SLAGizmoEventType::CtrlUp) { - m_ctrl_kar_filter.reset_count(); - m_mode = control_down ? EMode::PointSelection : EMode::FeatureSelection; - restore_scene_raycasters_state(); - } else if (action == SLAGizmoEventType::Delete) { m_selected_features.reset(); - m_selection_raycasters.clear(); + m_selected_sphere_raycasters.clear(); m_parent.request_extra_frame(); } else if (action == SLAGizmoEventType::Escape) { if (!m_selected_features.first.feature.has_value()) return false; else { - if (m_selected_features.second.feature.has_value()) - m_selected_features.second.feature.reset(); - else - m_selected_features.first.feature.reset(); + if (m_selected_features.second.feature.has_value()) { + remove_selected_sphere_raycaster(SEL_SPHERE_2_ID); + m_selected_features.second.feature.reset(); + } + else { + remove_selected_sphere_raycaster(SEL_SPHERE_1_ID); + m_selected_features.first.feature.reset(); + } } } @@ -503,7 +544,6 @@ void GLGizmoMeasure::on_set_state() { if (m_state == Off) { m_parent.toggle_sla_auxiliaries_visibility(true, nullptr, -1); - m_ctrl_kar_filter.reset_count(); m_shift_kar_filter.reset_count(); m_curr_feature.reset(); m_curr_point_on_feature_position.reset(); @@ -566,7 +606,7 @@ void GLGizmoMeasure::on_render() Vec3f normal_on_model; size_t model_facet_idx; const bool mouse_on_object = m_raycaster->unproject_on_mesh(m_mouse_pos, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); - const bool is_hovering_on_feature = (m_mode == EMode::PointSelection || m_mode == EMode::CenterSelection) && m_hover_id != -1; + const bool is_hovering_on_feature = m_mode == EMode::PointSelection && m_hover_id != -1; auto update_circle = [this, inv_zoom]() { if (m_last_inv_zoom != inv_zoom || m_last_circle != m_curr_feature) { @@ -583,14 +623,13 @@ void GLGizmoMeasure::on_render() }; if (m_mode == EMode::FeatureSelection || m_mode == EMode::PointSelection) { - if ((m_hover_id == SELECTION_1_ID && boost::algorithm::istarts_with(m_selected_features.first.source, _u8L("Center"))) || - (m_hover_id == SELECTION_2_ID && boost::algorithm::istarts_with(m_selected_features.second.source, _u8L("Center")))) { - // Skip feature detection if hovering on a selected center - m_curr_feature.reset(); + if (m_hover_id == SEL_SPHERE_1_ID || m_hover_id == SEL_SPHERE_2_ID) { + // Skip feature detection if hovering on a selected point/center m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, PLANE_ID); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID); + m_curr_feature.reset(); m_curr_point_on_feature_position.reset(); } else { @@ -618,15 +657,12 @@ void GLGizmoMeasure::on_render() case Measure::SurfaceFeatureType::Edge: { m_raycasters.insert({ EDGE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, EDGE_ID, *m_cylinder.mesh_raycaster) }); - if (m_curr_feature->get_extra_point().has_value()) - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); break; } case Measure::SurfaceFeatureType::Circle: { update_circle(); m_raycasters.insert({ CIRCLE_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CIRCLE_ID, *m_circle.mesh_raycaster) }); - m_raycasters.insert({ POINT_ID, m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, POINT_ID, *m_sphere.mesh_raycaster) }); break; } case Measure::SurfaceFeatureType::Plane: @@ -781,72 +817,69 @@ void GLGizmoMeasure::on_render() case Measure::SurfaceFeatureType::Circle: { const auto& [center, radius, normal] = feature.get_circle(); - // render center + // render circle + const Transform3d circle_matrix = Transform3d::Identity(); + set_matrix_uniforms(circle_matrix); if (update_raycasters_transform) { + set_emission_uniform(colors.front(), hover); + m_circle.model.set_color(colors.front()); + m_circle.model.render(); + auto it = m_raycasters.find(CIRCLE_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(circle_matrix); + } + else { + GLModel circle; + GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); + circle.init_from(std::move(circle_geometry)); + set_emission_uniform(colors.front(), hover); + circle.set_color(colors.front()); + circle.render(); + } + // render center + if (colors.size() > 1) { const Transform3d center_matrix = Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom); set_matrix_uniforms(center_matrix); - set_emission_uniform(colors.front(), hover); - m_sphere.model.set_color(colors.front()); + set_emission_uniform(colors.back(), hover); + m_sphere.model.set_color(colors.back()); m_sphere.model.render(); auto it = m_raycasters.find(POINT_ID); if (it != m_raycasters.end() && it->second != nullptr) it->second->set_transform(center_matrix); } - // render circle - if (m_mode != EMode::CenterSelection) { - const Transform3d circle_matrix = Transform3d::Identity(); - set_matrix_uniforms(circle_matrix); - if (update_raycasters_transform) { - set_emission_uniform(colors.back(), hover); - m_circle.model.set_color(colors.back()); - m_circle.model.render(); - auto it = m_raycasters.find(CIRCLE_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(circle_matrix); - } - else { - GLModel circle; - GLModel::Geometry circle_geometry = init_torus_data(64, 16, center.cast(), float(radius), 5.0f * inv_zoom, normal.cast(), Transform3f::Identity()); - circle.init_from(std::move(circle_geometry)); - set_emission_uniform(colors.back(), hover); - circle.set_color(colors.back()); - circle.render(); - } - } break; } case Measure::SurfaceFeatureType::Edge: { const auto& [from, to] = feature.get_edge(); - // render extra point + // render edge + const Transform3d edge_matrix = Geometry::translation_transform(from) * + Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * + Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); + set_matrix_uniforms(edge_matrix); + set_emission_uniform(colors.front(), hover); + m_cylinder.model.set_color(colors.front()); + m_cylinder.model.render(); if (update_raycasters_transform) { + auto it = m_raycasters.find(EDGE_ID); + if (it != m_raycasters.end() && it->second != nullptr) + it->second->set_transform(edge_matrix); + } + + // render extra point + if (colors.size() > 1) { const std::optional extra = feature.get_extra_point(); if (extra.has_value()) { const Transform3d point_matrix = Geometry::translation_transform(*extra) * Geometry::scale_transform(inv_zoom); set_matrix_uniforms(point_matrix); - set_emission_uniform(colors.front(), hover); - m_sphere.model.set_color(colors.front()); + set_emission_uniform(colors.back(), hover); + m_sphere.model.set_color(colors.back()); m_sphere.model.render(); auto it = m_raycasters.find(POINT_ID); if (it != m_raycasters.end() && it->second != nullptr) it->second->set_transform(point_matrix); } } - // render edge - if (m_mode != EMode::CenterSelection) { - const Transform3d edge_matrix = Geometry::translation_transform(from) * - Eigen::Quaternion::FromTwoVectors(Vec3d::UnitZ(), to - from) * - Geometry::scale_transform({ (double)inv_zoom, (double)inv_zoom, (to - from).norm() }); - set_matrix_uniforms(edge_matrix); - set_emission_uniform(colors.back(), hover); - m_cylinder.model.set_color(colors.back()); - m_cylinder.model.render(); - if (update_raycasters_transform) { - auto it = m_raycasters.find(EDGE_ID); - if (it != m_raycasters.end() && it->second != nullptr) - it->second->set_transform(edge_matrix); - } - } break; } case Measure::SurfaceFeatureType::Plane: @@ -881,11 +914,31 @@ void GLGizmoMeasure::on_render() }; if (m_curr_feature.has_value()) { + // render hovered feature + std::vector colors; - if (m_selected_features.first.feature.has_value() && *m_curr_feature == *m_selected_features.first.feature) - colors.emplace_back(hovering_color()); - else if (m_selected_features.second.feature.has_value() && *m_curr_feature == *m_selected_features.second.feature) - colors.emplace_back(hovering_color()); + if (m_selected_features.first.feature.has_value() && *m_curr_feature == *m_selected_features.first.feature) { + // hovering over the 1st selected feature + if (m_selected_features.first.is_center) + // hovering over a center + colors = { NEUTRAL_COLOR, hovering_color() }; + else if (is_feature_with_center(*m_selected_features.first.feature)) + // hovering over a feature with center + colors = { hovering_color(), NEUTRAL_COLOR }; + else + colors = { hovering_color() }; + } + else if (m_selected_features.second.feature.has_value() && *m_curr_feature == *m_selected_features.second.feature) { + // hovering over the 2nd selected feature + if (m_selected_features.second.is_center) + // hovering over a center + colors = { NEUTRAL_COLOR, hovering_color() }; + else if (is_feature_with_center(*m_selected_features.second.feature)) + // hovering over a feature with center + colors = { hovering_color(), NEUTRAL_COLOR }; + else + colors = { hovering_color() }; + } else { switch (m_curr_feature->get_type()) { @@ -898,8 +951,12 @@ void GLGizmoMeasure::on_render() case Measure::SurfaceFeatureType::Edge: case Measure::SurfaceFeatureType::Circle: { - colors.emplace_back((m_hover_id == POINT_ID) ? hover_selection_color() : hovering_color()); - colors.emplace_back(hovering_color()); + if (m_selected_features.first.is_center && m_curr_feature == m_selected_features.first.source) + colors = { SELECTED_1ST_COLOR, NEUTRAL_COLOR }; + else if (m_selected_features.second.is_center && m_curr_feature == m_selected_features.second.source) + colors = { SELECTED_2ND_COLOR, NEUTRAL_COLOR }; + else + colors = { hovering_color(), hovering_color() }; break; } case Measure::SurfaceFeatureType::Plane: @@ -914,28 +971,76 @@ void GLGizmoMeasure::on_render() } if (m_selected_features.first.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.first.feature)) { - const std::vector colors = { SELECTED_1ST_COLOR }; - render_feature(*m_selected_features.first.feature, colors, inv_zoom, m_hover_id == SELECTION_1_ID, false); - if (m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Point) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_1_ID; }); - if (it != m_selection_raycasters.end()) - (*it)->set_transform(Geometry::translation_transform(m_selected_features.first.feature->get_point()) * Geometry::scale_transform(inv_zoom)); + // render 1st selected feature + + std::optional feature_to_render; + std::vector colors; + bool requires_raycaster_update = false; + if (m_hover_id == SEL_SPHERE_1_ID && (m_selected_features.first.is_center || is_feature_with_center(*m_selected_features.first.feature))) { + // hovering over a center + feature_to_render = m_selected_features.first.source; + colors = { NEUTRAL_COLOR, SELECTED_1ST_COLOR }; + requires_raycaster_update = true; + } + else if (is_feature_with_center(*m_selected_features.first.feature)) { + // hovering over a feature with center + feature_to_render = m_selected_features.first.feature; + colors = { SELECTED_1ST_COLOR, NEUTRAL_COLOR }; + requires_raycaster_update = true; + } + else { + feature_to_render = m_selected_features.first.feature; + colors = { SELECTED_1ST_COLOR }; + requires_raycaster_update = m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Point; + } + + render_feature(*feature_to_render, colors, inv_zoom, m_hover_id == SEL_SPHERE_1_ID, false); + + if (requires_raycaster_update) { + auto it = std::find_if(m_selected_sphere_raycasters.begin(), m_selected_sphere_raycasters.end(), + [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SEL_SPHERE_1_ID; }); + if (it != m_selected_sphere_raycasters.end()) + (*it)->set_transform(Geometry::translation_transform(get_feature_offset(*m_selected_features.first.feature)) * Geometry::scale_transform(inv_zoom)); } } + if (m_selected_features.second.feature.has_value() && (!m_curr_feature.has_value() || *m_curr_feature != *m_selected_features.second.feature)) { - const std::vector colors = { SELECTED_2ND_COLOR }; - render_feature(*m_selected_features.second.feature, colors, inv_zoom, m_hover_id == SELECTION_2_ID, false); - if (m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Point) { - auto it = std::find_if(m_selection_raycasters.begin(), m_selection_raycasters.end(), - [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SELECTION_2_ID; }); - if (it != m_selection_raycasters.end()) - (*it)->set_transform(Geometry::translation_transform(m_selected_features.second.feature->get_point()) * Geometry::scale_transform(inv_zoom)); + // render 2nd selected feature + + std::optional feature_to_render; + std::vector colors; + bool requires_raycaster_update = false; + if (m_hover_id == SEL_SPHERE_2_ID && (m_selected_features.second.is_center || is_feature_with_center(*m_selected_features.second.feature))) { + // hovering over a center + feature_to_render = m_selected_features.second.source; + colors = { NEUTRAL_COLOR, SELECTED_2ND_COLOR }; + requires_raycaster_update = true; + } + else if (is_feature_with_center(*m_selected_features.second.feature)) { + // hovering over a feature with center + feature_to_render = m_selected_features.second.feature; + colors = { SELECTED_2ND_COLOR, NEUTRAL_COLOR }; + requires_raycaster_update = true; + } + else { + feature_to_render = m_selected_features.second.feature; + colors = { SELECTED_2ND_COLOR }; + requires_raycaster_update = m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Point; + } + + render_feature(*feature_to_render, colors, inv_zoom, m_hover_id == SEL_SPHERE_2_ID, false); + + if (requires_raycaster_update) { + auto it = std::find_if(m_selected_sphere_raycasters.begin(), m_selected_sphere_raycasters.end(), + [](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == SEL_SPHERE_2_ID; }); + if (it != m_selected_sphere_raycasters.end()) + (*it)->set_transform(Geometry::translation_transform(get_feature_offset(*m_selected_features.second.feature)) * Geometry::scale_transform(inv_zoom)); } } if (is_hovering_on_feature && m_curr_point_on_feature_position.has_value()) { if (m_hover_id != POINT_ID) { + // render point on feature while SHIFT is pressed const Transform3d matrix = Geometry::translation_transform(*m_curr_point_on_feature_position) * Geometry::scale_transform(inv_zoom); set_matrix_uniforms(matrix); const ColorRGBA color = hover_selection_color(); @@ -1600,7 +1705,8 @@ static void add_strings_row_to_table(ImGuiWrapper& imgui, const std::string& col void GLGizmoMeasure::render_debug_dialog() { auto add_feature_data = [this](const SelectedFeatures::Item& item) { - add_strings_row_to_table(*m_imgui, "Type", ImGuiWrapper::COL_ORANGE_LIGHT, item.source, ImGui::GetStyleColorVec4(ImGuiCol_Text)); + const std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id); + add_strings_row_to_table(*m_imgui, "Type", ImGuiWrapper::COL_ORANGE_LIGHT, text, ImGui::GetStyleColorVec4(ImGuiCol_Text)); switch (item.feature->get_type()) { case Measure::SurfaceFeatureType::Point: @@ -1646,7 +1752,6 @@ void GLGizmoMeasure::render_debug_dialog() { case EMode::FeatureSelection: { txt = "Feature selection"; break; } case EMode::PointSelection: { txt = "Point selection"; break; } - case EMode::CenterSelection: { txt = "Center selection"; break; } default: { assert(false); break; } } add_strings_row_to_table(*m_imgui, "Mode", ImGuiWrapper::COL_ORANGE_LIGHT, txt, ImGui::GetStyleColorVec4(ImGuiCol_Text)); @@ -1730,17 +1835,16 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit text = _u8L("Unselect feature"); color = SELECTED_2ND_COLOR; } - else if (m_hover_id == SELECTION_1_ID) { - text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); + else if (m_hover_id == SEL_SPHERE_1_ID) { + text = _u8L("Unselect point"); color = SELECTED_1ST_COLOR; } - else if (m_hover_id == SELECTION_2_ID) { - text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); + else if (m_hover_id == SEL_SPHERE_2_ID) { + text = _u8L("Unselect point"); color = SELECTED_2ND_COLOR; } else { - text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : - (m_mode == EMode::CenterSelection) ? _u8L("Select center") : _u8L("Select feature"); + text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); color = SELECTED_2ND_COLOR; } } @@ -1750,14 +1854,13 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit text = _u8L("Unselect feature"); color = SELECTED_1ST_COLOR; } - else if (m_hover_id == SELECTION_1_ID) { - text = (m_mode == EMode::CenterSelection) ? _u8L("Unselect center") : _u8L("Unselect point"); + else if (m_hover_id == SEL_SPHERE_1_ID) { + text = _u8L("Unselect point"); color = SELECTED_1ST_COLOR; } } if (text.empty()) { - text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : - (m_mode == EMode::CenterSelection) ? _u8L("Select center") : _u8L("Select feature"); + text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); color = m_selected_features.first.feature.has_value() ? SELECTED_2ND_COLOR : SELECTED_1ST_COLOR; } } @@ -1776,11 +1879,6 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ++row_count; } - if (m_mode != EMode::CenterSelection && feature_has_center(m_curr_feature)) { - add_strings_row_to_table(*m_imgui, _u8L("Shift") + "+" + CTRL_STR, ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Enable center selection"), ImGui::GetStyleColorVec4(ImGuiCol_Text)); - ++row_count; - } - if (m_selected_features.first.feature.has_value()) { add_strings_row_to_table(*m_imgui, _u8L("Delete"), ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Restart selection"), ImGui::GetStyleColorVec4(ImGuiCol_Text)); ++row_count; @@ -1806,7 +1904,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit } // add dummy rows to keep dialog size fixed - for (unsigned int i = row_count; i < 5; ++i) { + for (unsigned int i = row_count; i < 4; ++i) { add_strings_row_to_table(*m_imgui, " ", ImGuiWrapper::COL_ORANGE_LIGHT, " ", ImGui::GetStyleColorVec4(ImGuiCol_Text)); } @@ -1819,17 +1917,20 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ImGui::Separator(); const ImGuiTableFlags flags = ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersH; if (ImGui::BeginTable("Selection", 2, flags)) { - auto format_item_text = [use_inches, &units](const SelectedFeatures::Item& item) { - std::string txt = item.feature.has_value() ? item.source : _u8L("None"); - if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) { - auto [center, radius, normal] = item.feature->get_circle(); - const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); - radius = (on_circle - center).norm(); - if (use_inches) - radius = ObjectManipulation::mm_to_in * radius; - txt += " (" + _u8L("Diameter:") + " " + format_double(2.0 * radius) + units + ")"; - } - return txt; + auto format_item_text = [this, use_inches, &units](const SelectedFeatures::Item& item) { + if (!item.feature.has_value()) + return _u8L("None"); + + std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id); + if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) { + auto [center, radius, normal] = item.feature->get_circle(); + const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); + radius = (on_circle - center).norm(); + if (use_inches) + radius = ObjectManipulation::mm_to_in * radius; + text += " (" + _u8L("Diameter:") + " " + format_double(2.0 * radius) + units + ")"; + } + return text; }; add_strings_row_to_table(*m_imgui, _u8L("Selection") + " 1:", ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR), format_item_text(m_selected_features.first), @@ -1842,7 +1943,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit m_imgui->disabled_begin(!m_selected_features.first.feature.has_value()); if (m_imgui->button(_u8L("Restart selection"))) { m_selected_features.reset(); - m_selection_raycasters.clear(); + m_selected_sphere_raycasters.clear(); m_imgui->set_requires_extra_frame(); } m_imgui->disabled_end(); @@ -1938,7 +2039,16 @@ void GLGizmoMeasure::on_unregister_raycasters_for_picking() m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo); m_parent.set_raycaster_gizmos_on_top(false); m_raycasters.clear(); - m_selection_raycasters.clear(); + m_selected_sphere_raycasters.clear(); +} + +void GLGizmoMeasure::remove_selected_sphere_raycaster(int id) +{ + auto it = std::find_if(m_selected_sphere_raycasters.begin(), m_selected_sphere_raycasters.end(), + [id](std::shared_ptr item) { return SceneRaycaster::decode_id(SceneRaycaster::EType::Gizmo, item->get_id()) == id; }); + if (it != m_selected_sphere_raycasters.end()) + m_selected_sphere_raycasters.erase(it); + m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, id); } } // namespace GUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 1672e8b74e..1e4330e955 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -24,20 +24,19 @@ class GLGizmoMeasure : public GLGizmoBase enum class EMode : unsigned char { FeatureSelection, - PointSelection, - CenterSelection + PointSelection }; struct SelectedFeatures { struct Item { - std::string source; + bool is_center{ false }; + std::optional source; std::optional feature; bool operator == (const Item& other) const { - if (this->source != other.source) return false; - return this->feature == other.feature; + return this->is_center == other.is_center && this->source == other.source && this->feature == other.feature; } bool operator != (const Item& other) const { @@ -45,7 +44,8 @@ class GLGizmoMeasure : public GLGizmoBase } void reset() { - source.clear(); + is_center = false; + source.reset(); feature.reset(); } }; @@ -106,7 +106,8 @@ class GLGizmoMeasure : public GLGizmoBase std::vector m_plane_models_cache; std::map> m_raycasters; - std::vector> m_selection_raycasters; + // used to keep the raycasters for point/center spheres + std::vector> m_selected_sphere_raycasters; std::optional m_curr_feature; std::optional m_curr_point_on_feature_position; struct SceneRaycasterState @@ -126,7 +127,6 @@ class GLGizmoMeasure : public GLGizmoBase Vec2d m_mouse_pos{ Vec2d::Zero() }; - KeyAutoRepeatFilter m_ctrl_kar_filter; KeyAutoRepeatFilter m_shift_kar_filter; SelectedFeatures m_selected_features; @@ -174,6 +174,8 @@ protected: virtual void on_render_input_window(float x, float y, float bottom_limit) override; virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; + + void remove_selected_sphere_raycaster(int id); }; } // namespace GUI From 93a3ee501980c70e0a3805fe798c0392c601b24f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 12:51:37 +0100 Subject: [PATCH 88/99] Gizmo measure - Show radius of single selected circle, to allow for object scaling --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 105 ++++++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 1 + 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 43d55addda..27051a8e6d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -422,8 +422,7 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) m_selected_sphere_raycasters.push_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, SEL_SPHERE_1_ID, *m_sphere.mesh_raycaster)); } - if (m_selected_features != selected_features_old && m_selected_features.second.feature.has_value()) - m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); + update_measurement_result(); m_imgui->set_requires_extra_frame(); @@ -469,7 +468,7 @@ void GLGizmoMeasure::data_changed() m_last_inv_zoom = 0.0f; m_last_plane_idx = -1; if (m_pending_scale) { - m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); + update_measurement_result(); m_pending_scale = false; } else @@ -517,8 +516,10 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po m_parent.request_extra_frame(); } else if (action == SLAGizmoEventType::Escape) { - if (!m_selected_features.first.feature.has_value()) + if (!m_selected_features.first.feature.has_value()) { + update_measurement_result(); return false; + } else { if (m_selected_features.second.feature.has_value()) { remove_selected_sphere_raycaster(SEL_SPHERE_2_ID); @@ -528,6 +529,8 @@ bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_po remove_selected_sphere_raycaster(SEL_SPHERE_1_ID); m_selected_features.first.feature.reset(); } + + update_measurement_result(); } } @@ -1135,7 +1138,10 @@ void GLGizmoMeasure::render_dimensioning() { static SelectedFeatures last_selected_features; - if (!m_selected_features.first.feature.has_value() || !m_selected_features.second.feature.has_value()) + if (!m_selected_features.first.feature.has_value()) + return; + + if (!m_selected_features.second.feature.has_value() && m_selected_features.first.feature->get_type() != Measure::SurfaceFeatureType::Circle) return; GLShaderProgram* shader = wxGetApp().get_shader("flat"); @@ -1343,7 +1349,8 @@ void GLGizmoMeasure::render_dimensioning() const Vec3d new_center = selection.get_bounding_box().center(); const TrafoData trafo_data(ratio, old_center, new_center); scale_feature(*m_selected_features.first.feature, trafo_data); - scale_feature(*m_selected_features.second.feature, trafo_data); + if (m_selected_features.second.feature.has_value()) + scale_feature(*m_selected_features.second.feature, trafo_data); // update measure on next call to data_changed() m_pending_scale = true; @@ -1646,41 +1653,51 @@ void GLGizmoMeasure::render_dimensioning() glsafe(::glDisable(GL_DEPTH_TEST)); - if (m_selected_features.second.feature.has_value()) { - const bool has_distance = m_measurement_result.has_distance_data(); + const bool has_distance = m_measurement_result.has_distance_data(); - const Measure::SurfaceFeature* f1 = &(*m_selected_features.first.feature); - const Measure::SurfaceFeature* f2 = &(*m_selected_features.second.feature); - Measure::SurfaceFeatureType ft1 = f1->get_type(); - Measure::SurfaceFeatureType ft2 = f2->get_type(); - - // Order features by type so following conditions are simple. - if (ft1 > ft2) { - std::swap(ft1, ft2); - std::swap(f1, f2); - } - - // If there is an angle to show, draw the arc: - if (ft1 == Measure::SurfaceFeatureType::Edge && ft2 == Measure::SurfaceFeatureType::Edge) - arc_edge_edge(*f1, *f2); - else if (ft1 == Measure::SurfaceFeatureType::Edge && ft2 == Measure::SurfaceFeatureType::Plane) - arc_edge_plane(*f1, *f2); - else if (ft1 == Measure::SurfaceFeatureType::Plane && ft2 == Measure::SurfaceFeatureType::Plane) - arc_plane_plane(*f1, *f2); - - if (has_distance){ - // Where needed, draw the extension of the edge to where the dist is measured: - if (ft1 == Measure::SurfaceFeatureType::Point && ft2 == Measure::SurfaceFeatureType::Edge) - point_edge(*f1, *f2); - - // Render the arrow between the points that the backend passed: - const Measure::DistAndPoints& dap = m_measurement_result.distance_infinite.has_value() - ? *m_measurement_result.distance_infinite - : *m_measurement_result.distance_strict; - point_point(dap.from, dap.to, dap.dist); - } + const Measure::SurfaceFeature* f1 = &(*m_selected_features.first.feature); + const Measure::SurfaceFeature* f2 = nullptr; + std::unique_ptr temp_feature; + if (m_selected_features.second.feature.has_value()) + f2 = &(*m_selected_features.second.feature); + else { + assert(m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Circle); + temp_feature = std::make_unique(std::get<0>(m_selected_features.first.feature->get_circle())); + f2 = temp_feature.get(); } - + + if (!m_selected_features.second.feature.has_value() && m_selected_features.first.feature->get_type() != Measure::SurfaceFeatureType::Circle) + return; + + Measure::SurfaceFeatureType ft1 = f1->get_type(); + Measure::SurfaceFeatureType ft2 = f2->get_type(); + + // Order features by type so following conditions are simple. + if (ft1 > ft2) { + std::swap(ft1, ft2); + std::swap(f1, f2); + } + + // If there is an angle to show, draw the arc: + if (ft1 == Measure::SurfaceFeatureType::Edge && ft2 == Measure::SurfaceFeatureType::Edge) + arc_edge_edge(*f1, *f2); + else if (ft1 == Measure::SurfaceFeatureType::Edge && ft2 == Measure::SurfaceFeatureType::Plane) + arc_edge_plane(*f1, *f2); + else if (ft1 == Measure::SurfaceFeatureType::Plane && ft2 == Measure::SurfaceFeatureType::Plane) + arc_plane_plane(*f1, *f2); + + if (has_distance){ + // Where needed, draw the extension of the edge to where the dist is measured: + if (ft1 == Measure::SurfaceFeatureType::Point && ft2 == Measure::SurfaceFeatureType::Edge) + point_edge(*f1, *f2); + + // Render the arrow between the points that the backend passed: + const Measure::DistAndPoints& dap = m_measurement_result.distance_infinite.has_value() + ? *m_measurement_result.distance_infinite + : *m_measurement_result.distance_strict; + point_point(dap.from, dap.to, dap.dist); + } + glsafe(::glEnable(GL_DEPTH_TEST)); shader->stop_using(); @@ -2051,5 +2068,15 @@ void GLGizmoMeasure::remove_selected_sphere_raycaster(int id) m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo, id); } +void GLGizmoMeasure::update_measurement_result() +{ + if (!m_selected_features.first.feature.has_value()) + m_measurement_result = Measure::MeasurementResult(); + else if (m_selected_features.second.feature.has_value()) + m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature, m_measuring.get()); + else if (!m_selected_features.second.feature.has_value() && m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Circle) + m_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, Measure::SurfaceFeature(std::get<0>(m_selected_features.first.feature->get_circle())), m_measuring.get()); +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 1e4330e955..4652a171b7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -176,6 +176,7 @@ protected: virtual void on_unregister_raycasters_for_picking() override; void remove_selected_sphere_raycaster(int id); + void update_measurement_result(); }; } // namespace GUI From 6533eb2a53edf28313bd07da0526b66cbd0e9c60 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 13:04:48 +0100 Subject: [PATCH 89/99] Fixed warnings --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 27051a8e6d..c1e153c886 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -487,17 +487,6 @@ static bool feature_has_center(std::optional feature) bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { - auto activate_center_selection = [this, shift_down, control_down](SLAGizmoEventType action) { - bool ret = false; - switch (action) - { - case SLAGizmoEventType::CtrlDown: { ret = shift_down && feature_has_center(m_curr_feature); break; } - case SLAGizmoEventType::ShiftDown: { ret = control_down && feature_has_center(m_curr_feature); break; } - default: { break; } - } - return ret; - }; - if (action == SLAGizmoEventType::ShiftDown) { if (m_shift_kar_filter.is_first()) { m_mode = EMode::PointSelection; @@ -598,8 +587,6 @@ void GLGizmoMeasure::on_render() // if (m_parent.is_mouse_dragging()) // return; - const Selection& selection = m_parent.get_selection(); - update_if_needed(); const Camera& camera = wxGetApp().plater()->get_camera(); From f0811873563e1d7f2923dccb4e7a7d4ff5f7ec71 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 30 Nov 2022 13:07:49 +0100 Subject: [PATCH 90/99] Fixed warning --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index c1e153c886..bf321bb785 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -310,7 +310,6 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) return false; if (m_hover_id != -1) { - SelectedFeatures selected_features_old = m_selected_features; m_mouse_left_down = true; auto detect_current_item = [this]() { From 220104dbe22dde4a82a4d84b5bef63bed2178a6a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 1 Dec 2022 12:47:06 +0100 Subject: [PATCH 91/99] Measure gizmo - Fixed sychronization of imgui dialog with current hovering/selection state --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 94 +++++++++++++++++++++--- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index bf321bb785..1ddd805b71 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1831,22 +1831,61 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ColorRGBA color; if (m_selected_features.second.feature.has_value()) { if (m_selected_features.first.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { + // hovering over 1st selected feature text = _u8L("Unselect feature"); color = SELECTED_1ST_COLOR; } + else if (m_hover_id == SEL_SPHERE_1_ID) { + if (m_selected_features.first.is_center) { + // hovering over center selected as 1st feature + text = _u8L("Unselect center"); + color = SELECTED_1ST_COLOR; + } + else if (is_feature_with_center(*m_selected_features.first.feature)) { + // hovering over center of 1st selected feature + text = _u8L("Select center"); + color = SELECTED_1ST_COLOR; + } + else { + // hovering over point selected as 1st feature + text = _u8L("Unselect point"); + color = SELECTED_1ST_COLOR; + } + } + else if (m_selected_features.first.is_center && m_selected_features.first.source == m_curr_feature) { + // hovering over feature whose center is selected as 1st feature + text = _u8L("Select feature"); + color = SELECTED_1ST_COLOR; + } else if (m_selected_features.second.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { + // hovering over 2nd selected feature text = _u8L("Unselect feature"); color = SELECTED_2ND_COLOR; } - else if (m_hover_id == SEL_SPHERE_1_ID) { - text = _u8L("Unselect point"); - color = SELECTED_1ST_COLOR; - } else if (m_hover_id == SEL_SPHERE_2_ID) { - text = _u8L("Unselect point"); + if (m_selected_features.second.is_center) { + // hovering over center selected as 2nd feature + text = _u8L("Unselect feature"); + color = SELECTED_2ND_COLOR; + } + else if (is_feature_with_center(*m_selected_features.second.feature)) { + // hovering over center of 2nd selected feature + text = _u8L("Select center"); + color = SELECTED_2ND_COLOR; + } + else { + // hovering over point selected as 2nd feature + text = _u8L("Unselect point"); + color = SELECTED_2ND_COLOR; + } + } + else if (m_selected_features.second.is_center && m_selected_features.second.source == m_curr_feature) { + // hovering over feature whose center is selected as 2nd feature + text = _u8L("Select feature"); color = SELECTED_2ND_COLOR; } else { + // 1st feature selected text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); color = SELECTED_2ND_COLOR; } @@ -1854,20 +1893,51 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit else { if (m_selected_features.first.feature.has_value()) { if (m_selected_features.first.feature == m_curr_feature && m_mode == EMode::FeatureSelection) { + // hovering over 1st selected feature text = _u8L("Unselect feature"); color = SELECTED_1ST_COLOR; } - else if (m_hover_id == SEL_SPHERE_1_ID) { - text = _u8L("Unselect point"); - color = SELECTED_1ST_COLOR; + else { + if (m_hover_id == SEL_SPHERE_1_ID) { + if (m_selected_features.first.is_center) { + // hovering over center selected as 1st feature + text = _u8L("Unselect feature"); + color = SELECTED_1ST_COLOR; + } + else if (is_feature_with_center(*m_selected_features.first.feature)) { + // hovering over center of 1st selected feature + text = _u8L("Select center"); + color = SELECTED_1ST_COLOR; + } + else { + // hovering over point selected as 1st feature + text = _u8L("Unselect point"); + color = SELECTED_1ST_COLOR; + } + } + else { + if (m_selected_features.first.is_center && m_selected_features.first.source == m_curr_feature) { + // hovering over feature whose center is selected as 1st feature + text = _u8L("Select feature"); + color = SELECTED_1ST_COLOR; + } + else { + // 1st feature selected + text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); + color = SELECTED_2ND_COLOR; + } + } } } - if (text.empty()) { + else { + // nothing is selected text = (m_mode == EMode::PointSelection) ? _u8L("Select point") : _u8L("Select feature"); - color = m_selected_features.first.feature.has_value() ? SELECTED_2ND_COLOR : SELECTED_1ST_COLOR; + color = SELECTED_1ST_COLOR; } } + assert(!text.empty()); + m_imgui->text_colored(ImGui::GetStyleColorVec4(ImGuiCol_Text), text); ImGui::SameLine(); const ImVec2 pos = ImGui::GetCursorScreenPos(); @@ -1985,7 +2055,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit if (use_inches) distance = ObjectManipulation::mm_to_in * distance; ImGui::PushID("ClipboardDistanceInfinite"); - add_measure_row_to_table(_u8L("Distance Infinite"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(distance) + units, + add_measure_row_to_table(_u8L("Distance"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(distance) + units, ImGui::GetStyleColorVec4(ImGuiCol_Text)); ++measure_row_count; ImGui::PopID(); @@ -1996,7 +2066,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit if (use_inches) distance = ObjectManipulation::mm_to_in * distance; ImGui::PushID("ClipboardDistanceStrict"); - add_measure_row_to_table(_u8L("Distance Strict"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(distance) + units, + add_measure_row_to_table(_u8L("Distance"), ImGuiWrapper::COL_ORANGE_LIGHT, format_double(distance) + units, ImGui::GetStyleColorVec4(ImGuiCol_Text)); ++measure_row_count; ImGui::PopID(); From eeea803be576f266cc2be36e10f55273cd3fa6ee Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 1 Dec 2022 13:31:22 +0100 Subject: [PATCH 92/99] Measurement: tweaking of the tolerances, ransacing the whole border --- src/libslic3r/Measure.cpp | 324 ++++++++++++++++++++------------------ 1 file changed, 175 insertions(+), 149 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 37bf68e83d..3d96c351c5 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -18,7 +18,7 @@ static std::pair get_center_and_radius(const std::vector& { Vec2ds out; double z = 0.; - for (const Vec3d pt : points) { + for (const Vec3d& pt : points) { Vec3d pt_transformed = trafo * pt; z = pt_transformed.z(); out.emplace_back(pt_transformed.x(), pt_transformed.y()); @@ -29,6 +29,14 @@ static std::pair get_center_and_radius(const std::vector& return std::make_pair(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius); } +static bool circle_fit_is_ok(const std::vector& pts, const Vec3d& center, double radius) +{ + for (const Vec3d& pt : pts) + if (std::abs((pt - center).norm() - radius) > 0.05) + return false; + return true; +} + static std::array orthonormal_basis(const Vec3d& v) { std::array ret; @@ -246,10 +254,7 @@ void MeasuringImpl::update_planes() void MeasuringImpl::extract_features() { - auto are_angles_same = [](double a, double b) { return Slic3r::is_approx(a,b); }; - auto are_lengths_same = [](double a, double b) { return Slic3r::is_approx(a,b); }; - - std::vector angles; + std::vector angles; // placed in outer scope to prevent reallocations std::vector lengths; @@ -267,175 +272,196 @@ void MeasuringImpl::extract_features() if (border.size() <= 1) continue; - // Given an idx into border, return the index that is idx+offset position, - // while taking into account the need for warp-around and the fact that - // the first and last point are the same. - auto offset_to_index = [border_size = int(border.size())](int idx, int offset) -> int { - assert(std::abs(offset) < border_size); - int out = idx+offset; - if (out >= border_size) - out = out - border_size; - else if (out < 0) - out = border_size + out; + bool done = false; - return out; - }; + if (const auto& [center, radius] = get_center_and_radius(border, trafo); + (border.size()>4) && circle_fit_is_ok(border, center, radius)) { + // The whole border is one circle. Just add it into the list of features + // and we are done. - // First calculate angles at all the vertices. - angles.clear(); - lengths.clear(); - int first_different_angle_idx = 0; - for (int i=0; i M_PI) - angle = 2*M_PI - angle; + bool is_polygon = border.size()>4 && border.size()<=8; + bool lengths_match = std::all_of(border.begin()+2, border.end(), [is_polygon](const Vec3d& pt) { + return Slic3r::is_approx((pt - *((&pt)-1)).squaredNorm(), (*((&pt)-1) - *((&pt)-2)).squaredNorm(), is_polygon ? 0.01 : 0.01); + }); - angles.push_back(angle); - lengths.push_back(v2.norm()); - if (first_different_angle_idx == 0 && angles.size() > 1) { - if (! are_angles_same(angles.back(), angles[angles.size()-2])) - first_different_angle_idx = angles.size()-1; + if (lengths_match && (is_polygon || border.size() > 8)) { + if (is_polygon) { + // This is a polygon, add the separate edges with the center. + for (int j=0; j circles; - std::vector edges; - std::vector> circles_idxs; - //std::vector circles_lengths; - std::vector single_circle; // could be in loop-scope, but reallocations - double single_circle_length = 0.; - int first_pt_idx = offset_to_index(first_different_angle_idx, 1); - int i = first_pt_idx; - while (i != first_pt_idx || first_iter) { - if (are_angles_same(angles[i], angles[offset_to_index(i,-1)]) - && i != offset_to_index(first_pt_idx, -1) // not the last point - && i != start_idx ) { - // circle - if (! circle) { - circle = true; - single_circle.clear(); - single_circle_length = 0.; - start_idx = offset_to_index(i, -2); - single_circle = { border[start_idx], border[offset_to_index(start_idx,1)] }; - single_circle_length += lengths[offset_to_index(i, -1)]; + if (! done) { + // In this case, the border is not a circle and may contain circular + // segments. Try to find them and then add all remaining edges as edges. + + auto are_angles_same = [](double a, double b) { return Slic3r::is_approx(a,b,0.01); }; + auto are_lengths_same = [](double a, double b) { return Slic3r::is_approx(a,b,0.01); }; + + + // Given an idx into border, return the index that is idx+offset position, + // while taking into account the need for wrap-around and the fact that + // the first and last point are the same. + auto offset_to_index = [border_size = int(border.size())](int idx, int offset) -> int { + assert(std::abs(offset) < border_size); + int out = idx+offset; + if (out >= border_size) + out = out - border_size; + else if (out < 0) + out = border_size + out; + + return out; + }; + + // First calculate angles at all the vertices. + angles.clear(); + lengths.clear(); + int first_different_angle_idx = 0; + for (int i=0; i M_PI) + angle = 2*M_PI - angle; + + angles.push_back(angle); + lengths.push_back(v2.norm()); + if (first_different_angle_idx == 0 && angles.size() > 1) { + if (! are_angles_same(angles.back(), angles[angles.size()-2])) + first_different_angle_idx = angles.size()-1; } - single_circle.emplace_back(border[i]); - single_circle_length += lengths[i]; - } else { - if (circle && single_circle.size() >= 5) { // Less than 5 vertices? Not a circle. + } + assert(border.size() == angles.size()); + assert(border.size() == lengths.size()); + + // First go around the border and pick what might be circular segments. + // Save pair of indices to where such potential segments start and end. + // Also remember the length of these segments. + int start_idx = -1; + bool circle = false; + bool first_iter = true; + std::vector circles; + std::vector edges; + std::vector> circles_idxs; + //std::vector circles_lengths; + std::vector single_circle; // could be in loop-scope, but reallocations + double single_circle_length = 0.; + int first_pt_idx = offset_to_index(first_different_angle_idx, 1); + int i = first_pt_idx; + while (i != first_pt_idx || first_iter) { + if (are_angles_same(angles[i], angles[offset_to_index(i,-1)]) + && i != offset_to_index(first_pt_idx, -1) // not the last point + && i != start_idx ) { + // circle + if (! circle) { + circle = true; + single_circle.clear(); + single_circle_length = 0.; + start_idx = offset_to_index(i, -2); + single_circle = { border[start_idx], border[offset_to_index(start_idx,1)] }; + single_circle_length += lengths[offset_to_index(i, -1)]; + } single_circle.emplace_back(border[i]); single_circle_length += lengths[i]; + } else { + if (circle && single_circle.size() >= 5) { // Less than 5 vertices? Not a circle. + single_circle.emplace_back(border[i]); + single_circle_length += lengths[i]; - bool accept_circle = true; - { - // Check that lengths of internal (!!!) edges match. - int j = offset_to_index(start_idx, 3); - while (j != i) { - if (! are_lengths_same(lengths[offset_to_index(j,-1)], lengths[j])) { - accept_circle = false; - break; - } - j = offset_to_index(j, 1); - } - } - - if (accept_circle) { - const auto& [center, radius] = get_center_and_radius(single_circle, trafo); - - // Check that the fit went well. The tolerance is high, only to - // reject complete failures. - for (const Vec3d& pt : single_circle) { - if (std::abs((pt - center).norm() - radius) > 0.5) { - accept_circle = false; - break; + bool accept_circle = true; + { + // Check that lengths of internal (!!!) edges match. + int j = offset_to_index(start_idx, 3); + while (j != i) { + if (! are_lengths_same(lengths[offset_to_index(j,-1)], lengths[j])) { + accept_circle = false; + break; + } + j = offset_to_index(j, 1); } } - // If the segment subtends less than 90 degrees, throw it away. - accept_circle &= single_circle_length / radius > 0.9*M_PI/2.; - - // If this is all-around and 5 to 8 vertices, consider it a polygon. - bool is_polygon = start_idx == i && single_circle.size() <= 9 && single_circle.size() >= 6; - if (accept_circle) { - // Add the circle and remember indices into borders. - circles_idxs.emplace_back(start_idx, i); - if (is_polygon) { - for (int j=0; j<=i; ++j) // No wrap-around handling needed here. - edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, - border[j==0 ? border.size()-1 : j-1], border[j], - std::make_optional(center))); - } - else + const auto& [center, radius] = get_center_and_radius(single_circle, trafo); + + // Check that the fit went well. The tolerance is high, only to + // reject complete failures. + accept_circle &= circle_fit_is_ok(single_circle, center, radius); + + // If the segment subtends less than 90 degrees, throw it away. + accept_circle &= single_circle_length / radius > 0.9*M_PI/2.; + + if (accept_circle) { + // Add the circle and remember indices into borders. + circles_idxs.emplace_back(start_idx, i); circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius)); + } } } + circle = false; } - circle = false; - } - // Take care of the wrap around. - first_iter = false; - i = offset_to_index(i, 1); - } - - // We have the circles. Now go around again and pick edges, while jumping over circles. - if (circles_idxs.empty()) { - // Just add all edges. - for (int i=1; i 1 || circles_idxs.front().first != circles_idxs.front().second) { + // There is at least one circular segment. Start at its end and add edges until the start of the next one. + int i = circles_idxs.front().second; + int circle_idx = 1; + while (true) { + i = offset_to_index(i, 1); + edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[offset_to_index(i,-1)], border[i])); + if (circle_idx < int(circles_idxs.size()) && i == circles_idxs[circle_idx].first) { + i = circles_idxs[circle_idx].second; + ++circle_idx; + } + if (i == circles_idxs.front().first) + break; } - if (i == circles_idxs.front().first) - break; } - } - // Merge adjacent edges where needed. - assert(std::all_of(edges.begin(), edges.end(), - [](const SurfaceFeature& f) { return f.get_type() == SurfaceFeatureType::Edge; })); - for (int i=edges.size()-1; i>=0; --i) { - const auto& [first_start, first_end] = edges[i==0 ? edges.size()-1 : i-1].get_edge(); - const auto& [second_start, second_end] = edges[i].get_edge(); + // Merge adjacent edges where needed. + assert(std::all_of(edges.begin(), edges.end(), + [](const SurfaceFeature& f) { return f.get_type() == SurfaceFeatureType::Edge; })); + for (int i=edges.size()-1; i>=0; --i) { + const auto& [first_start, first_end] = edges[i==0 ? edges.size()-1 : i-1].get_edge(); + const auto& [second_start, second_end] = edges[i].get_edge(); - if (Slic3r::is_approx(first_end, second_start) - && Slic3r::is_approx((first_end-first_start).normalized().dot((second_end-second_start).normalized()), 1.)) { - // The edges have the same direction and share a point. Merge them. - edges[i==0 ? edges.size()-1 : i-1] = SurfaceFeature(SurfaceFeatureType::Edge, first_start, second_end); - edges.erase(edges.begin() + i); + if (Slic3r::is_approx(first_end, second_start) + && Slic3r::is_approx((first_end-first_start).normalized().dot((second_end-second_start).normalized()), 1.)) { + // The edges have the same direction and share a point. Merge them. + edges[i==0 ? edges.size()-1 : i-1] = SurfaceFeature(SurfaceFeatureType::Edge, first_start, second_end); + edges.erase(edges.begin() + i); + } } - } - // Now move the circles and edges into the feature list for the plane. - assert(std::all_of(circles.begin(), circles.end(), [](const SurfaceFeature& f) { - return f.get_type() == SurfaceFeatureType::Circle; - })); - assert(std::all_of(edges.begin(), edges.end(), [](const SurfaceFeature& f) { - return f.get_type() == SurfaceFeatureType::Edge; - })); - plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(circles.begin()), - std::make_move_iterator(circles.end())); - plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(edges.begin()), - std::make_move_iterator(edges.end())); + // Now move the circles and edges into the feature list for the plane. + assert(std::all_of(circles.begin(), circles.end(), [](const SurfaceFeature& f) { + return f.get_type() == SurfaceFeatureType::Circle; + })); + assert(std::all_of(edges.begin(), edges.end(), [](const SurfaceFeature& f) { + return f.get_type() == SurfaceFeatureType::Edge; + })); + plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(circles.begin()), + std::make_move_iterator(circles.end())); + plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(edges.begin()), + std::make_move_iterator(edges.end())); + } } // The last surface feature is the plane itself. From 954cd105e03945d2cfc96a0df5c4bd24b8d6e1b2 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 1 Dec 2022 13:34:29 +0100 Subject: [PATCH 93/99] Fixed warnings --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 1ddd805b71..31cd005bec 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -82,17 +82,6 @@ static std::string point_on_feature_type_as_string(Measure::SurfaceFeatureType t return ret; } -static std::string center_on_feature_type_as_string(Measure::SurfaceFeatureType type) -{ - std::string ret; - switch (type) { - case Measure::SurfaceFeatureType::Edge: { ret = _u8L("Center of edge"); break; } - case Measure::SurfaceFeatureType::Circle: { ret = _u8L("Center of circle"); break; } - default: { assert(false); break; } - } - return ret; -} - static GLModel::Geometry init_plane_data(const indexed_triangle_set& its, const std::vector>& planes_triangles, int idx) { assert(0 <= idx && idx < (int)planes_triangles.size()); @@ -477,13 +466,6 @@ void GLGizmoMeasure::data_changed() m_is_editing_distance_first_frame = true; } -static bool feature_has_center(std::optional feature) -{ - return feature.has_value() ? - (feature->get_type() == Measure::SurfaceFeatureType::Circle || (feature->get_type() == Measure::SurfaceFeatureType::Edge && feature->get_extra_point().has_value())) - : false; -} - bool GLGizmoMeasure::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { if (action == SLAGizmoEventType::ShiftDown) { From 2f8e2c5e8006274d1bf89ca3e59be655e44faf85 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 1 Dec 2022 14:56:33 +0100 Subject: [PATCH 94/99] Measure gizmo - Fixed missing raycaster when promoting a point as 1st selected feature --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 31cd005bec..05da490825 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -336,7 +336,7 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) }; auto requires_sphere_raycaster_for_picking = [this](const SelectedFeatures::Item& item) { - if (m_mode == EMode::PointSelection) + if (m_mode == EMode::PointSelection || item.feature->get_type() == Measure::SurfaceFeatureType::Point) return true; else if (m_mode == EMode::FeatureSelection) { if (is_feature_with_center(*item.feature)) From cc8a6a3fff0280b99e947aa7f22c33b04e864bae Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 2 Dec 2022 07:56:11 +0100 Subject: [PATCH 95/99] Follow-up of 85195ac79fb2b7016b05ffff5eb33a483a4d06c2 - Fixed synch of selected features in imgui dialog --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 05da490825..4cb9682b6f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -82,6 +82,17 @@ static std::string point_on_feature_type_as_string(Measure::SurfaceFeatureType t return ret; } +static std::string center_on_feature_type_as_string(Measure::SurfaceFeatureType type) +{ + std::string ret; + switch (type) { + case Measure::SurfaceFeatureType::Edge: { ret = _u8L("Center of edge"); break; } + case Measure::SurfaceFeatureType::Circle: { ret = _u8L("Center of circle"); break; } + default: { assert(false); break; } + } + return ret; +} + static GLModel::Geometry init_plane_data(const indexed_triangle_set& its, const std::vector>& planes_triangles, int idx) { assert(0 <= idx && idx < (int)planes_triangles.size()); @@ -1976,7 +1987,8 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit if (!item.feature.has_value()) return _u8L("None"); - std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id); + std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) : + item.is_center ? center_on_feature_type_as_string(item.source->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id); if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) { auto [center, radius, normal] = item.feature->get_circle(); const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true); From 456e61c7d3bafaed03d00b8b8e895470a8e5fa9c Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 2 Dec 2022 07:42:02 +0100 Subject: [PATCH 96/99] Measurement: Fixed edge detection on single-triangle planes --- src/libslic3r/Measure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 3d96c351c5..6368f30f57 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -227,7 +227,7 @@ void MeasuringImpl::update_planes() // In case of broken meshes, this loop might be infinite. Break // out in case it is clearly going bad. - if (last_border.size() > 3*facets.size()) + if (last_border.size() > 3*facets.size()+1) goto PLANE_FAILURE; } while (he != he_start); From 210273e12fc29c8274f9d17a991f83230c8d9470 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 2 Dec 2022 12:39:49 +0100 Subject: [PATCH 97/99] Fixed differences after rebase to master --- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 4cb9682b6f..a2d2518d6a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -866,15 +866,12 @@ void GLGizmoMeasure::on_render() } case Measure::SurfaceFeatureType::Plane: { - // no need to render the plane in case it is rendered with the same color as the volume in the 3D scene - if (colors.front() != m_parent.get_selection().get_first_volume()->render_color) { - const auto& [idx, normal, pt] = feature.get_plane(); - assert(idx < m_plane_models_cache.size()); - set_matrix_uniforms(Transform3d::Identity()); - set_emission_uniform(colors.front(), hover); - m_plane_models_cache[idx].set_color(colors.front()); - m_plane_models_cache[idx].render(); - } + const auto& [idx, normal, pt] = feature.get_plane(); + assert(idx < m_plane_models_cache.size()); + set_matrix_uniforms(Transform3d::Identity()); + set_emission_uniform(colors.front(), hover); + m_plane_models_cache[idx].set_color(colors.front()); + m_plane_models_cache[idx].render(); if (update_raycasters_transform) { auto it = m_raycasters.find(PLANE_ID); if (it != m_raycasters.end() && it->second != nullptr) From e04e8c55cfc0498bb665f6fb515f3a8fcea64796 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 2 Dec 2022 14:21:18 +0100 Subject: [PATCH 98/99] Improved performance of GLModel::render: The way the OpenGL version was checked was quite inefficient --- src/slic3r/GUI/OpenGLManager.cpp | 47 +++++++++++++------------ src/slic3r/GUI/OpenGLManager.hpp | 13 ++++--- src/slic3r/GUI/SendSystemInfoDialog.cpp | 4 +-- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 2924470e07..0366031d29 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -37,20 +37,20 @@ std::string gl_get_string_safe(GLenum param, const std::string& default_value) return std::string((value != nullptr) ? value : default_value); } -const std::string& OpenGLManager::GLInfo::get_version() const +const std::string& OpenGLManager::GLInfo::get_version_string() const { if (!m_detected) detect(); - return m_version; + return m_version_string; } -const std::string& OpenGLManager::GLInfo::get_glsl_version() const +const std::string& OpenGLManager::GLInfo::get_glsl_version_string() const { if (!m_detected) detect(); - return m_glsl_version; + return m_glsl_version_string; } const std::string& OpenGLManager::GLInfo::get_vendor() const @@ -71,7 +71,7 @@ const std::string& OpenGLManager::GLInfo::get_renderer() const bool OpenGLManager::GLInfo::is_mesa() const { - return boost::icontains(m_version, "mesa"); + return m_version_is_mesa; } int OpenGLManager::GLInfo::get_max_tex_size() const @@ -97,13 +97,19 @@ float OpenGLManager::GLInfo::get_max_anisotropy() const return m_max_anisotropy; } +static Semver parse_version_string(const std::string& version); + void OpenGLManager::GLInfo::detect() const { - *const_cast(&m_version) = gl_get_string_safe(GL_VERSION, "N/A"); - *const_cast(&m_glsl_version) = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION, "N/A"); + *const_cast(&m_version_string) = gl_get_string_safe(GL_VERSION, "N/A"); + *const_cast(&m_glsl_version_string) = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION, "N/A"); *const_cast(&m_vendor) = gl_get_string_safe(GL_VENDOR, "N/A"); *const_cast(&m_renderer) = gl_get_string_safe(GL_RENDERER, "N/A"); + *const_cast(&m_version) = parse_version_string(m_version_string); + *const_cast(&m_version_is_mesa) = boost::icontains(m_version_string, "mesa"); + *const_cast(&m_glsl_version) = parse_version_string(m_glsl_version_string); + int* max_tex_size = const_cast(&m_max_tex_size); glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, max_tex_size)); @@ -119,16 +125,16 @@ void OpenGLManager::GLInfo::detect() const *const_cast(&m_detected) = true; } -static bool version_greater_or_equal_to(const std::string& version, unsigned int major, unsigned int minor) +static Semver parse_version_string(const std::string& version) { if (version == "N/A") - return false; + return Semver::invalid(); std::vector tokens; boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on); if (tokens.empty()) - return false; + return Semver::invalid(); #if ENABLE_OPENGL_ES const std::string version_container = (tokens.size() > 1 && boost::istarts_with(tokens[1], "ES")) ? tokens[2] : tokens[0]; @@ -150,20 +156,15 @@ static bool version_greater_or_equal_to(const std::string& version, unsigned int if (numbers.size() > 1) gl_minor = ::atoi(numbers[1].c_str()); - if (gl_major < major) - return false; - else if (gl_major > major) - return true; - else - return gl_minor >= minor; + return Semver(gl_major, gl_minor, 0); } bool OpenGLManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { if (!m_detected) detect(); - - return version_greater_or_equal_to(m_version, major, minor); + + return m_version >= Semver(major, minor, 0); } bool OpenGLManager::GLInfo::is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const @@ -171,7 +172,7 @@ bool OpenGLManager::GLInfo::is_glsl_version_greater_or_equal_to(unsigned int maj if (!m_detected) detect(); - return version_greater_or_equal_to(m_glsl_version, major, minor); + return m_glsl_version >= Semver(major, minor, 0); } // If formatted for github, plaintext with OpenGL extensions enclosed into

. @@ -378,13 +379,13 @@ bool OpenGLManager::init_gl() wxString message = from_u8((boost::format( #if ENABLE_OPENGL_ES _utf8(L("PrusaSlicer requires OpenGL ES 2.0 capable graphics driver to run correctly, \n" - "while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); + "while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version_string() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); #elif ENABLE_GL_CORE_PROFILE _utf8(L("PrusaSlicer requires OpenGL %s capable graphics driver to run correctly, \n" - "while OpenGL version %s, render %s, vendor %s was detected."))) % (s_gl_info.is_core_profile() ? "3.3" : "2.0") % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); + "while OpenGL version %s, render %s, vendor %s was detected."))) % (s_gl_info.is_core_profile() ? "3.3" : "2.0") % s_gl_info.get_version_string() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); #else _utf8(L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n" - "while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); + "while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version_string() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); #endif // ENABLE_OPENGL_ES message += "\n"; message += _L("You may need to update your graphics card driver."); @@ -423,7 +424,7 @@ bool OpenGLManager::init_gl() // WHQL: 4.6.14800 Compatibility Profile Context 22.6.1 30.0.21023.1015 // Non-WHQL: 4.6.0 Compatibility Profile Context 22.8.1.220810 std::regex version_rgx(R"(Compatibility\sProfile\sContext\s(\d+)\.(\d+)\.(\d+))"); - if (std::smatch matches; std::regex_search(gl_info.get_version(), matches, version_rgx) && matches.size() == 4) { + if (std::smatch matches; std::regex_search(gl_info.get_version_string(), matches, version_rgx) && matches.size() == 4) { int version_major = std::stoi(matches[1].str()); int version_minor = std::stoi(matches[2].str()); int version_patch = std::stoi(matches[3].str()); diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 5c810d83ef..ece9009622 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -31,16 +31,21 @@ public: int m_max_tex_size{ 0 }; float m_max_anisotropy{ 0.0f }; - std::string m_version; - std::string m_glsl_version; + std::string m_version_string; + Semver m_version = Semver::invalid(); + bool m_version_is_mesa = false; + + std::string m_glsl_version_string; + Semver m_glsl_version = Semver::invalid(); + std::string m_vendor; std::string m_renderer; public: GLInfo() = default; - const std::string& get_version() const; - const std::string& get_glsl_version() const; + const std::string& get_version_string() const; + const std::string& get_glsl_version_string() const; const std::string& get_vendor() const; const std::string& get_renderer() const; diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 298b3242d5..dfb442d18c 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -504,8 +504,8 @@ static std::string generate_system_info_json() #endif // _WIN32 pt::ptree opengl_node; - opengl_node.put("Version", OpenGLManager::get_gl_info().get_version()); - opengl_node.put("GLSLVersion", OpenGLManager::get_gl_info().get_glsl_version()); + opengl_node.put("Version", OpenGLManager::get_gl_info().get_version_string()); + opengl_node.put("GLSLVersion", OpenGLManager::get_gl_info().get_glsl_version_string()); opengl_node.put("Vendor", OpenGLManager::get_gl_info().get_vendor()); opengl_node.put("Renderer", OpenGLManager::get_gl_info().get_renderer()); // Generate list of OpenGL extensions: From 6f18f8f7845e52699efa3e3f8ac2fcdadd0ffe12 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 5 Dec 2022 10:24:30 +0100 Subject: [PATCH 99/99] Tech ENABLE_RAYCAST_PICKING set as default --- src/libslic3r/Model.hpp | 2 - src/libslic3r/Technologies.hpp | 5 +- src/slic3r/GUI/3DBed.cpp | 56 ------ src/slic3r/GUI/3DBed.hpp | 8 - src/slic3r/GUI/3DScene.cpp | 48 ----- src/slic3r/GUI/3DScene.hpp | 4 - src/slic3r/GUI/Camera.cpp | 46 ----- src/slic3r/GUI/Camera.hpp | 9 - src/slic3r/GUI/GLCanvas3D.cpp | 194 +------------------ src/slic3r/GUI/GLCanvas3D.hpp | 10 - src/slic3r/GUI/GLSelectionRectangle.cpp | 11 -- src/slic3r/GUI/GLSelectionRectangle.hpp | 6 - src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 119 +----------- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 37 ---- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 6 - src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 78 -------- src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp | 14 -- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 81 +------- src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp | 16 -- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 27 --- src/slic3r/GUI/Gizmos/GLGizmoMove.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 3 - src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 29 --- src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 11 -- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 24 --- src/slic3r/GUI/Gizmos/GLGizmoScale.hpp | 4 - src/slic3r/GUI/Gizmos/GLGizmoSimplify.hpp | 3 - src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 120 ++---------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 15 -- src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 4 - src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 15 -- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 3 - src/slic3r/GUI/MeshUtils.cpp | 7 - src/slic3r/GUI/MeshUtils.hpp | 25 --- src/slic3r/GUI/SceneRaycaster.cpp | 4 - src/slic3r/GUI/SceneRaycaster.hpp | 4 - src/slic3r/Utils/RaycastManager.cpp | 4 - tests/libslic3r/test_color.cpp | 16 -- 39 files changed, 30 insertions(+), 1046 deletions(-) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 6fb2bc923d..1cd6c34143 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -762,9 +762,7 @@ public: // The triangular model. const TriangleMesh& mesh() const { return *m_mesh.get(); } -#if ENABLE_RAYCAST_PICKING std::shared_ptr mesh_ptr() const { return m_mesh; } -#endif // ENABLE_RAYCAST_PICKING void set_mesh(const TriangleMesh &mesh) { m_mesh = std::make_shared(mesh); } void set_mesh(TriangleMesh &&mesh) { m_mesh = std::make_shared(std::move(mesh)); } void set_mesh(const indexed_triangle_set &mesh) { m_mesh = std::make_shared(mesh); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index f707b0f21d..4e6d2106b1 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -28,6 +28,8 @@ #define DISABLE_GCODEVIEWER_INSTANCED_MODELS 1 // Enable Measure Gizmo debug window #define ENABLE_MEASURE_GIZMO_DEBUG 0 +// Enable scene raycast picking debug window +#define ENABLE_RAYCAST_PICKING_DEBUG 0 // Enable rendering of objects using environment map @@ -61,9 +63,6 @@ #define ENABLE_PROCESS_G2_G3_LINES (1 && ENABLE_2_6_0_ALPHA1) // Enable fix of used filament data exported to gcode file #define ENABLE_USED_FILAMENT_POST_PROCESS (1 && ENABLE_2_6_0_ALPHA1) -// Enable picking using raytracing -#define ENABLE_RAYCAST_PICKING (1 && ENABLE_LEGACY_OPENGL_REMOVAL) -#define ENABLE_RAYCAST_PICKING_DEBUG (0 && ENABLE_RAYCAST_PICKING) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 1402584028..a7e70bc430 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -252,10 +252,8 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c m_axes.set_origin({ 0.0, 0.0, static_cast(GROUND_Z) }); m_axes.set_stem_length(0.1f * static_cast(m_build_volume.bounding_volume().max_size())); -#if ENABLE_RAYCAST_PICKING // unregister from picking wxGetApp().plater()->canvas3D()->remove_raycasters_for_picking(SceneRaycaster::EType::Bed); -#endif // ENABLE_RAYCAST_PICKING // Let the calee to update the UI. return true; @@ -309,11 +307,7 @@ void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, glsafe(::glEnable(GL_DEPTH_TEST)); #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_model.model.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR); -#else - m_model.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR); -#endif // ENABLE_RAYCAST_PICKING #else m_model.set_color(-1, picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR); #endif // ENABLE_LEGACY_OPENGL_REMOVAL @@ -355,11 +349,7 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box() const out.merge(out.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, out.max.z())); #endif // ENABLE_WORLD_COORDINATE // extend to contain model, if any -#if ENABLE_RAYCAST_PICKING BoundingBoxf3 model_bb = m_model.model.get_bounding_box(); -#else - BoundingBoxf3 model_bb = m_model.get_bounding_box(); -#endif // ENABLE_RAYCAST_PICKING if (model_bb.defined) { model_bb.translate(m_model_offset); out.merge(model_bb); @@ -409,16 +399,12 @@ void Bed3D::init_triangles() init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); } -#if ENABLE_RAYCAST_PICKING if (m_model.model.get_filename().empty() && m_model.mesh_raycaster == nullptr) // register for picking register_raycasters_for_picking(init_data, Transform3d::Identity()); -#endif // ENABLE_RAYCAST_PICKING m_triangles.init_from(std::move(init_data)); -#if ENABLE_RAYCAST_PICKING m_triangles.set_color(DEFAULT_MODEL_COLOR); -#endif // ENABLE_RAYCAST_PICKING } void Bed3D::init_gridlines() @@ -798,17 +784,9 @@ void Bed3D::render_model() if (m_model_filename.empty()) return; -#if ENABLE_RAYCAST_PICKING if (m_model.model.get_filename() != m_model_filename && m_model.model.init_from_file(m_model_filename)) { -#else - if (m_model.get_filename() != m_model_filename && m_model.init_from_file(m_model_filename)) { -#endif // ENABLE_RAYCAST_PICKING #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_model.model.set_color(DEFAULT_MODEL_COLOR); -#else - m_model.set_color(DEFAULT_MODEL_COLOR); -#endif // ENABLE_RAYCAST_PICKING #else m_model.set_color(-1, DEFAULT_MODEL_COLOR); #endif // ENABLE_LEGACY_OPENGL_REMOVAL @@ -816,20 +794,14 @@ void Bed3D::render_model() // move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad m_model_offset = to_3d(m_build_volume.bounding_volume2d().center(), -0.03); -#if ENABLE_RAYCAST_PICKING // register for picking register_raycasters_for_picking(m_model.model.get_geometry(), Geometry::translation_transform(m_model_offset)); -#endif // ENABLE_RAYCAST_PICKING // update extended bounding box m_extended_bounding_box = this->calc_extended_bounding_box(); } -#if ENABLE_RAYCAST_PICKING if (!m_model.model.get_filename().empty()) { -#else - if (!m_model.get_filename().empty()) { -#endif // ENABLE_RAYCAST_PICKING GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { shader->start_using(); @@ -844,11 +816,7 @@ void Bed3D::render_model() glsafe(::glPushMatrix()); glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z())); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_model.model.render(); -#else - m_model.render(); -#endif // ENABLE_RAYCAST_PICKING #if !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopMatrix()); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL @@ -914,23 +882,14 @@ void Bed3D::render_default(bool bottom, bool picking, bool show_texture) glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); -#if ENABLE_RAYCAST_PICKING const bool has_model = !m_model.model.get_filename().empty(); -#else - const bool has_model = !m_model.get_filename().empty(); -#endif // ENABLE_RAYCAST_PICKING - if (!has_model && !bottom) { // draw background glsafe(::glDepthMask(GL_FALSE)); -#if !ENABLE_RAYCAST_PICKING - m_triangles.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR); -#endif // !ENABLE_RAYCAST_PICKING m_triangles.render(); glsafe(::glDepthMask(GL_TRUE)); } -#if ENABLE_RAYCAST_PICKING if (show_texture) { // draw grid #if ENABLE_GL_CORE_PROFILE @@ -942,19 +901,6 @@ void Bed3D::render_default(bool bottom, bool picking, bool show_texture) } else render_contour(view_matrix, projection_matrix); -#else - if (!picking && show_texture) { - // draw grid -#if ENABLE_GL_CORE_PROFILE - if (!OpenGLManager::get_gl_info().is_core_profile()) -#endif // ENABLE_GL_CORE_PROFILE - glsafe(::glLineWidth(1.5f * m_scale_factor)); - m_gridlines.set_color(has_model && !bottom ? DEFAULT_SOLID_GRID_COLOR : DEFAULT_TRANSPARENT_GRID_COLOR); - m_gridlines.render(); - } - else if (!show_texture) - render_contour(view_matrix, projection_matrix); -#endif // ENABLE_RAYCAST_PICKING glsafe(::glDisable(GL_BLEND)); @@ -1047,7 +993,6 @@ void Bed3D::release_VBOs() } #endif // !ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING void Bed3D::register_raycasters_for_picking(const GLModel::Geometry& geometry, const Transform3d& trafo) { assert(m_model.mesh_raycaster == nullptr); @@ -1066,7 +1011,6 @@ void Bed3D::register_raycasters_for_picking(const GLModel::Geometry& geometry, c m_model.mesh_raycaster = std::make_unique(std::make_shared(std::move(its))); wxGetApp().plater()->canvas3D()->add_raycaster_for_picking(SceneRaycaster::EType::Bed, 0, *m_model.mesh_raycaster, trafo); } -#endif // ENABLE_RAYCAST_PICKING } // GUI } // Slic3r diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 7f0dff19d0..c12674b4a7 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -8,9 +8,7 @@ #else #include "GLModel.hpp" #endif // ENABLE_WORLD_COORDINATE -#if ENABLE_RAYCAST_PICKING #include "MeshUtils.hpp" -#endif // ENABLE_RAYCAST_PICKING #include "libslic3r/BuildVolume.hpp" #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -111,11 +109,7 @@ private: GLTexture m_texture; // temporary texture shown until the main texture has still no levels compressed GLTexture m_temp_texture; -#if ENABLE_RAYCAST_PICKING PickingModel m_model; -#else - GLModel m_model; -#endif // ENABLE_RAYCAST_PICKING Vec3d m_model_offset{ Vec3d::Zero() }; #if !ENABLE_LEGACY_OPENGL_REMOVAL unsigned int m_vbo_id{ 0 }; @@ -205,9 +199,7 @@ private: void release_VBOs(); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING void register_raycasters_for_picking(const GLModel::Geometry& geometry, const Transform3d& trafo); -#endif // ENABLE_RAYCAST_PICKING }; } // GUI diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 7ab01bebf4..4bf05555c8 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -807,27 +807,17 @@ int GLVolumeCollection::load_object_volume( const ModelVolume *model_volume = model_object->volumes[volume_idx]; const int extruder_id = model_volume->extruder_id(); const ModelInstance *instance = model_object->instances[instance_idx]; -#if ENABLE_RAYCAST_PICKING std::shared_ptr mesh = model_volume->mesh_ptr(); -#else - const TriangleMesh &mesh = model_volume->mesh(); -#endif // ENABLE_RAYCAST_PICKING this->volumes.emplace_back(new GLVolume()); GLVolume& v = *this->volumes.back(); v.set_color(color_from_model_volume(*model_volume)); #if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SMOOTH_NORMALS v.model.init_from(*mesh, true); -#if ENABLE_RAYCAST_PICKING v.mesh_raycaster = std::make_unique(mesh); -#endif // ENABLE_RAYCAST_PICKING #else -#if ENABLE_RAYCAST_PICKING v.model.init_from(*mesh); v.mesh_raycaster = std::make_unique(mesh); -#else - v.model.init_from(mesh); -#endif // ENABLE_RAYCAST_PICKING #endif // ENABLE_SMOOTH_NORMALS #else #if ENABLE_SMOOTH_NORMALS @@ -893,9 +883,7 @@ void GLVolumeCollection::load_object_auxiliary( #else v.model.init_from(mesh); v.model.set_color((milestone == slaposPad) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR); -#if ENABLE_RAYCAST_PICKING v.mesh_raycaster = std::make_unique(std::make_shared(mesh)); -#endif // ENABLE_RAYCAST_PICKING #endif // ENABLE_SMOOTH_NORMALS #else #if ENABLE_SMOOTH_NORMALS @@ -954,13 +942,10 @@ int GLVolumeCollection::load_wipe_tower_preview( depth = std::max(depth, 10.f); float min_width = 30.f; -#if ENABLE_RAYCAST_PICKING const float scaled_brim_height = 0.2f / height; -#endif // ENABLE_RAYCAST_PICKING // We'll now create the box with jagged edge. y-coordinates of the pre-generated model // are shifted so that the front edge has y=0 and centerline of the back edge has y=depth: -#if ENABLE_RAYCAST_PICKING // We split the box in three main pieces, // the two laterals are identical and the central is the one containing the jagged geometry @@ -1061,22 +1046,6 @@ int GLVolumeCollection::load_wipe_tower_preview( tooth_mesh.merge(TriangleMesh(std::move(data))); data = generate_lateral(61.547f, 100.0f); tooth_mesh.merge(TriangleMesh(std::move(data))); -#else - float out_points_idx[][3] = { { 0, -depth, 0 }, { 0, 0, 0 }, { 38.453f, 0, 0 }, { 61.547f, 0, 0 }, { 100.0f, 0, 0 }, { 100.0f, -depth, 0 }, { 55.7735f, -10.0f, 0 }, { 44.2265f, 10.0f, 0 }, - { 38.453f, 0, 1 }, { 0, 0, 1 }, { 0, -depth, 1 }, { 100.0f, -depth, 1 }, { 100.0f, 0, 1 }, { 61.547f, 0, 1 }, { 55.7735f, -10.0f, 1 }, { 44.2265f, 10.0f, 1 } }; - static constexpr const int out_facets_idx[][3] = { - { 0, 1, 2 }, { 3, 4, 5 }, { 6, 5, 0 }, { 3, 5, 6 }, { 6, 2, 7 }, { 6, 0, 2 }, { 8, 9, 10 }, { 11, 12, 13 }, { 10, 11, 14 }, { 14, 11, 13 }, { 15, 8, 14 }, - { 8, 10, 14 }, { 3, 12, 4 }, { 3, 13, 12 }, { 6, 13, 3 }, { 6, 14, 13 }, { 7, 14, 6 }, { 7, 15, 14 }, { 2, 15, 7 }, { 2, 8, 15 }, { 1, 8, 2 }, { 1, 9, 8 }, - { 0, 9, 1 }, { 0, 10, 9 }, { 5, 10, 0 }, { 5, 11, 10 }, { 4, 11, 5 }, { 4, 12, 11 } }; - indexed_triangle_set its; - for (int i = 0; i < 16; ++i) - its.vertices.emplace_back(out_points_idx[i][0] / (100.f / min_width), - out_points_idx[i][1] + depth, out_points_idx[i][2]); - its.indices.reserve(28); - for (const int *face : out_facets_idx) - its.indices.emplace_back(face); - TriangleMesh tooth_mesh(std::move(its)); -#endif // ENABLE_RAYCAST_PICKING // We have the mesh ready. It has one tooth and width of min_width. We will now // append several of these together until we are close to the required width @@ -1084,14 +1053,9 @@ int GLVolumeCollection::load_wipe_tower_preview( size_t n = std::max(1, int(width / min_width)); // How many shall be merged? for (size_t i = 0; i < n; ++i) { mesh.merge(tooth_mesh); -#if ENABLE_RAYCAST_PICKING tooth_mesh.translate(100.0f, 0.0f, 0.0f); -#else - tooth_mesh.translate(min_width, 0.f, 0.f); -#endif // ENABLE_RAYCAST_PICKING } -#if ENABLE_RAYCAST_PICKING // Now we add the caps along the X axis const float scaled_brim_width_x = brim_width * n * width / min_width; auto generate_negx_cap = [&]() { @@ -1166,20 +1130,10 @@ int GLVolumeCollection::load_wipe_tower_preview( data = generate_posx_cap(); mesh.merge(TriangleMesh(std::move(data))); mesh.scale(Vec3f(width / (n * 100.0f), 1.0f, height)); // Scaling to proper width -#else - mesh.scale(Vec3f(width / (n * min_width), 1.f, height)); // Scaling to proper width -#endif // ENABLE_RAYCAST_PICKING } else mesh = make_cube(width, depth, height); -#if !ENABLE_RAYCAST_PICKING - // We'll make another mesh to show the brim (fixed layer height): - TriangleMesh brim_mesh = make_cube(width + 2.f * brim_width, depth + 2.f * brim_width, 0.2f); - brim_mesh.translate(-brim_width, -brim_width, 0.f); - mesh.merge(brim_mesh); -#endif // !ENABLE_RAYCAST_PICKING - volumes.emplace_back(new GLVolume(color)); GLVolume& v = *volumes.back(); #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -1189,9 +1143,7 @@ int GLVolumeCollection::load_wipe_tower_preview( #endif // ENABLE_OPENGL_ES v.model.init_from(mesh); v.model.set_color(color); -#if ENABLE_RAYCAST_PICKING v.mesh_raycaster = std::make_unique(std::make_shared(mesh)); -#endif // ENABLE_RAYCAST_PICKING #else v.indexed_vertex_array.load_mesh(mesh); #endif // ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 1e8897c4e0..a7146d61cf 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -10,9 +10,7 @@ #include "libslic3r/Color.hpp" #include "GLModel.hpp" -#if ENABLE_RAYCAST_PICKING #include "MeshUtils.hpp" -#endif // ENABLE_RAYCAST_PICKING #include #include @@ -393,10 +391,8 @@ public: #if ENABLE_LEGACY_OPENGL_REMOVAL GUI::GLModel model; -#if ENABLE_RAYCAST_PICKING // raycaster used for picking std::unique_ptr mesh_raycaster; -#endif // ENABLE_RAYCAST_PICKING #else // Interleaved triangles & normals with indexed triangles & quads. GLIndexedVertexArray indexed_vertex_array; diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 56980c43a5..a549d87da8 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -91,7 +91,6 @@ void Camera::select_view(const std::string& direction) look_at(m_target + m_distance * Vec3d::UnitY(), m_target, Vec3d::UnitZ()); } -#if ENABLE_RAYCAST_PICKING double Camera::get_near_left() const { switch (m_type) @@ -163,7 +162,6 @@ double Camera::get_near_height() const return 2.0 / m_projection_matrix.matrix()(1, 1); } } -#endif // ENABLE_RAYCAST_PICKING double Camera::get_fov() const { @@ -177,7 +175,6 @@ double Camera::get_fov() const }; } -#if ENABLE_RAYCAST_PICKING void Camera::set_viewport(int x, int y, unsigned int w, unsigned int h) { #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -191,17 +188,6 @@ void Camera::apply_viewport() const { glsafe(::glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3])); } -#else -void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) -{ - glsafe(::glViewport(0, 0, w, h)); -#if ENABLE_LEGACY_OPENGL_REMOVAL - m_viewport = { 0, 0, int(w), int(h) }; -#else - glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data())); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL -} -#endif // ENABLE_RAYCAST_PICKING #if !ENABLE_LEGACY_OPENGL_REMOVAL void Camera::apply_view_matrix() @@ -260,37 +246,7 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa } #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING apply_projection(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second); -#else - switch (m_type) - { - default: - case EType::Ortho: - { - const double dz = m_frustrum_zs.second - m_frustrum_zs.first; - const double zz = m_frustrum_zs.first + m_frustrum_zs.second; - m_projection_matrix.matrix() << 1.0 / w, 0.0, 0.0, 0.0, - 0.0, 1.0 / h, 0.0, 0.0, - 0.0, 0.0, -2.0 / dz, -zz / dz, - 0.0, 0.0, 0.0, 1.0; - break; - } - case EType::Perspective: - { - const double n = m_frustrum_zs.first; - const double f = m_frustrum_zs.second; - const double dz = f - n; - const double zz = n + f; - const double fn = n * f; - m_projection_matrix.matrix() << n / w, 0.0, 0.0, 0.0, - 0.0, n / h, 0.0, 0.0, - 0.0, 0.0, -zz / dz, -2.0 * fn / dz, - 0.0, 0.0, -1.0, 0.0; - break; - } - } -#endif // ENABLE_RAYCAST_PICKING #else glsafe(::glMatrixMode(GL_PROJECTION)); glsafe(::glLoadIdentity()); @@ -315,7 +271,6 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa #endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_RAYCAST_PICKING void Camera::apply_projection(double left, double right, double bottom, double top, double near_z, double far_z) { assert(left != right && bottom != top && near_z != far_z); @@ -344,7 +299,6 @@ void Camera::apply_projection(double left, double right, double bottom, double t } } } -#endif // ENABLE_RAYCAST_PICKING void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor) { diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index b2672e14e5..dca7ba642e 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -89,33 +89,24 @@ public: double get_far_z() const { return m_frustrum_zs.second; } const std::pair& get_z_range() const { return m_frustrum_zs; } -#if ENABLE_RAYCAST_PICKING double get_near_left() const; double get_near_right() const; double get_near_top() const; double get_near_bottom() const; double get_near_width() const; double get_near_height() const; -#endif // ENABLE_RAYCAST_PICKING double get_fov() const; -#if ENABLE_RAYCAST_PICKING void set_viewport(int x, int y, unsigned int w, unsigned int h); void apply_viewport() const; -#else - void apply_viewport(int x, int y, unsigned int w, unsigned int h); -#endif // ENABLE_RAYCAST_PICKING #if !ENABLE_LEGACY_OPENGL_REMOVAL void apply_view_matrix(); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL // Calculates and applies the projection matrix tighting the frustrum z range around the given box. // If larger z span is needed, pass the desired values of near and far z (negative values are ignored) void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0); - -#if ENABLE_RAYCAST_PICKING void apply_projection(double left, double right, double bottom, double top, double near_z, double far_z); -#endif // ENABLE_RAYCAST_PICKING void zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultZoomToBoxMarginFactor); void zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor = DefaultZoomToVolumesMarginFactor); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9f2e7c0dad..0c505bc0b2 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1346,13 +1346,10 @@ void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObje m_render_sla_auxiliaries = visible; -#if ENABLE_RAYCAST_PICKING std::vector>* raycasters = get_raycasters_for_picking(SceneRaycaster::EType::Volume); -#endif // ENABLE_RAYCAST_PICKING for (GLVolume* vol : m_volumes.volumes) { -#if ENABLE_RAYCAST_PICKING - if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) + if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) && vol->composite_id.volume_id < 0) { vol->is_active = visible; @@ -1360,20 +1357,12 @@ void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObje if (it != raycasters->end()) (*it)->set_active(vol->is_active); } -#else - if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) - && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) - && vol->composite_id.volume_id < 0) - vol->is_active = visible; -#endif // ENABLE_RAYCAST_PICKING } } void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject* mo, int instance_idx, const ModelVolume* mv) { -#if ENABLE_RAYCAST_PICKING std::vector>* raycasters = get_raycasters_for_picking(SceneRaycaster::EType::Volume); -#endif // ENABLE_RAYCAST_PICKING for (GLVolume* vol : m_volumes.volumes) { if (vol->is_wipe_tower) vol->is_active = (visible && mo == nullptr); @@ -1404,11 +1393,10 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject } } } -#if ENABLE_RAYCAST_PICKING + auto it = std::find_if(raycasters->begin(), raycasters->end(), [vol](std::shared_ptr item) { return item->get_raycaster() == vol->mesh_raycaster.get(); }); if (it != raycasters->end()) (*it)->set_active(vol->is_active); -#endif // ENABLE_RAYCAST_PICKING } if (visible && !mo) @@ -1666,12 +1654,8 @@ void GLCanvas3D::render() // and the viewport was set incorrectly, leading to tripping glAsserts further down // the road (in apply_projection). That's why the minimum size is forced to 10. Camera& camera = wxGetApp().plater()->get_camera(); -#if ENABLE_RAYCAST_PICKING camera.set_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height())); camera.apply_viewport(); -#else - camera.apply_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height())); -#endif // ENABLE_RAYCAST_PICKING if (camera.requires_zoom_to_bed) { zoom_to_bed(); @@ -2266,9 +2250,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re #else #if ENABLE_LEGACY_OPENGL_REMOVAL volume.model.init_from(mesh); -#if ENABLE_RAYCAST_PICKING volume.mesh_raycaster = std::make_unique(std::make_shared(mesh)); -#endif // ENABLE_RAYCAST_PICKING #else volume.indexed_vertex_array.load_mesh(mesh); #endif // ENABLE_LEGACY_OPENGL_REMOVAL @@ -2284,13 +2266,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re #endif // ENABLE_LEGACY_OPENGL_REMOVAL #else #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING - const TriangleMesh& new_mesh = m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(); + const TriangleMesh& new_mesh = m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(); volume.model.init_from(new_mesh); volume.mesh_raycaster = std::make_unique(std::make_shared(new_mesh)); -#else - volume.model.init_from(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh()); -#endif // ENABLE_RAYCAST_PICKING #else volume.indexed_vertex_array.load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh()); #endif // ENABLE_LEGACY_OPENGL_REMOVAL @@ -2447,7 +2425,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re manip->set_dirty(); } -#if ENABLE_RAYCAST_PICKING // refresh volume raycasters for picking m_scene_raycaster.remove_raycasters(SceneRaycaster::EType::Volume); for (size_t i = 0; i < m_volumes.volumes.size(); ++i) { @@ -2464,7 +2441,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re m_scene_raycaster.remove_raycasters(SceneRaycaster::EType::Gizmo); if (curr_gizmo != nullptr && !m_selection.is_empty()) curr_gizmo->register_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING // and force this canvas to be redrawn. m_dirty = true; @@ -3010,11 +2986,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) // set_cursor(Standard); } else if (keyCode == WXK_CONTROL) { -#if ENABLE_RAYCAST_PICKING - if (m_mouse.dragging && !m_moving) { -#else - if (m_mouse.dragging) { -#endif // ENABLE_RAYCAST_PICKING + if (m_mouse.dragging && !m_moving) { // if the user releases CTRL while rotating the 3D scene // prevent from moving the selected volume m_mouse.drag.move_volume_idx = -1; @@ -3530,9 +3502,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (!evt.CmdDown()) m_mouse.drag.start_position_3D = m_mouse.scene_position; m_sequential_print_clearance_first_displacement = true; -#if !ENABLE_RAYCAST_PICKING - m_moving = true; -#endif // !ENABLE_RAYCAST_PICKING } } } @@ -3576,9 +3545,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } #if ENABLE_WORLD_COORDINATE -#if ENABLE_RAYCAST_PICKING m_moving = true; -#endif // ENABLE_RAYCAST_PICKING TransformationType trafo_type; trafo_type.set_relative(); m_selection.translate(cur_pos - m_mouse.drag.start_position_3D, trafo_type); @@ -3609,9 +3576,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // do not process the dragging if the left mouse was set down in another canvas else if (evt.LeftIsDown()) { // if dragging over blank area with left button, rotate -#if ENABLE_RAYCAST_PICKING if (!m_moving) { -#endif // ENABLE_RAYCAST_PICKING if ((any_gizmo_active || evt.CmdDown() || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) { const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.0) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.0); if (wxGetApp().app_config->get("use_free_camera") == "1") @@ -3630,9 +3595,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } m_mouse.drag.start_position_3D = Vec3d((double)pos.x(), (double)pos.y(), 0.0); -#if ENABLE_RAYCAST_PICKING } -#endif // ENABLE_RAYCAST_PICKING } else if (evt.MiddleIsDown() || evt.RightIsDown()) { // If dragging over blank area with right/middle button, pan. @@ -3657,9 +3620,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } else if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) { -#if ENABLE_RAYCAST_PICKING m_mouse.position = pos.cast(); -#endif // ENABLE_RAYCAST_PICKING if (m_layers_editing.state != LayersEditing::Unknown) { m_layers_editing.state = LayersEditing::Unknown; @@ -3685,9 +3646,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) deselect_all(); } else if (evt.RightUp()) { -#if !ENABLE_RAYCAST_PICKING - m_mouse.position = pos.cast(); -#endif // !ENABLE_RAYCAST_PICKING // forces a frame render to ensure that m_hover_volume_idxs is updated even when the user right clicks while // the context menu is already shown render(); @@ -4678,12 +4636,8 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const Camera camera; camera.set_type(camera_type); camera.set_scene_box(scene_bounding_box()); -#if ENABLE_RAYCAST_PICKING camera.set_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); camera.apply_viewport(); -#else - camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); -#endif // ENABLE_RAYCAST_PICKING camera.zoom_to_box(volumes_box); #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -4985,11 +4939,7 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT // restore the default framebuffer size to avoid flickering on the 3D scene -#if ENABLE_RAYCAST_PICKING wxGetApp().plater()->get_camera().apply_viewport(); -#else - wxGetApp().plater()->get_camera().apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); -#endif // ENABLE_RAYCAST_PICKING } bool GLCanvas3D::_init_toolbars() @@ -5456,7 +5406,6 @@ void GLCanvas3D::_refresh_if_shown_on_screen() } } -#if ENABLE_RAYCAST_PICKING void GLCanvas3D::_picking_pass() { if (!m_picking_enabled || m_mouse.dragging || m_mouse.position == Vec2d(DBL_MAX, DBL_MAX) || m_gizmos.is_dragging()) { @@ -5599,82 +5548,6 @@ void GLCanvas3D::_picking_pass() imgui.end(); #endif // ENABLE_RAYCAST_PICKING_DEBUG } -#else -void GLCanvas3D::_picking_pass() -{ - if (m_picking_enabled && !m_mouse.dragging && m_mouse.position != Vec2d(DBL_MAX, DBL_MAX) && !m_gizmos.is_dragging()) { - m_hover_volume_idxs.clear(); - - // Render the object for picking. - // FIXME This cannot possibly work in a multi - sampled context as the color gets mangled by the anti - aliasing. - // Better to use software ray - casting on a bounding - box hierarchy. - - if (m_multisample_allowed) - // This flag is often ignored by NVIDIA drivers if rendering into a screen buffer. - glsafe(::glDisable(GL_MULTISAMPLE)); - - glsafe(::glDisable(GL_BLEND)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - -#if !ENABLE_LEGACY_OPENGL_REMOVAL - m_camera_clipping_plane = m_gizmos.get_clipping_plane(); - if (m_camera_clipping_plane.is_active()) { - ::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data().data()); - ::glEnable(GL_CLIP_PLANE0); - } -#endif // !ENABLE_LEGACY_OPENGL_REMOVAL - _render_volumes_for_picking(); -#if !ENABLE_LEGACY_OPENGL_REMOVAL - if (m_camera_clipping_plane.is_active()) - ::glDisable(GL_CLIP_PLANE0); -#endif // !ENABLE_LEGACY_OPENGL_REMOVAL - -#if ENABLE_LEGACY_OPENGL_REMOVAL - const Camera& camera = wxGetApp().plater()->get_camera(); - _render_bed_for_picking(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward()); -#else - _render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward()); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL - - m_gizmos.render_current_gizmo_for_picking_pass(); - - if (m_multisample_allowed) - glsafe(::glEnable(GL_MULTISAMPLE)); - - int volume_id = -1; - int gizmo_id = -1; - - std::array color = { 0, 0, 0, 0 }; - const Size& cnv_size = get_canvas_size(); - bool inside = 0 <= m_mouse.position(0) && m_mouse.position(0) < cnv_size.get_width() && 0 <= m_mouse.position(1) && m_mouse.position(1) < cnv_size.get_height(); - if (inside) { - glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position.y() - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color.data())); - if (picking_checksum_alpha_channel(color[0], color[1], color[2]) == color[3]) { - // Only non-interpolated colors are valid, those have their lowest three bits zeroed. - // we reserve color = (0,0,0) for occluders (as the printbed) - // volumes' id are shifted by 1 - // see: _render_volumes_for_picking() - unsigned int id = picking_encode(color[0], color[1], color[2]); - volume_id = id - 1; - // gizmos' id are instead properly encoded by the color - gizmo_id = id; - } - } - if (0 <= volume_id && volume_id < (int)m_volumes.volumes.size()) { - // do not add the volume id if any gizmo is active and CTRL is pressed - if (m_gizmos.get_current_type() == GLGizmosManager::EType::Undefined || !wxGetKeyState(WXK_CONTROL)) - m_hover_volume_idxs.emplace_back(volume_id); - m_gizmos.set_hover_id(-1); - } - else - m_gizmos.set_hover_id(inside && (unsigned int)gizmo_id <= GLGizmoBase::BASE_ID ? ((int)GLGizmoBase::BASE_ID - gizmo_id) : -1); - - _update_volumes_hover_state(); - } -} -#endif // ENABLE_RAYCAST_PICKING void GLCanvas3D::_rectangular_selection_picking_pass() { @@ -5683,7 +5556,6 @@ void GLCanvas3D::_rectangular_selection_picking_pass() std::set idxs; if (m_picking_enabled) { -#if ENABLE_RAYCAST_PICKING const size_t width = std::max(m_rectangle_selection.get_width(), 1); const size_t height = std::max(m_rectangle_selection.get_height(), 1); @@ -5737,7 +5609,6 @@ void GLCanvas3D::_rectangular_selection_picking_pass() use_framebuffer = false; } } -#endif // ENABLE_RAYCAST_PICKING if (m_multisample_allowed) // This flag is often ignored by NVIDIA drivers if rendering into a screen buffer. @@ -5748,7 +5619,6 @@ void GLCanvas3D::_rectangular_selection_picking_pass() glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); -#if ENABLE_RAYCAST_PICKING const Camera& main_camera = wxGetApp().plater()->get_camera(); Camera framebuffer_camera; framebuffer_camera.set_type(main_camera.get_type()); @@ -5782,16 +5652,8 @@ void GLCanvas3D::_rectangular_selection_picking_pass() } _render_volumes_for_picking(*camera); -#else - _render_volumes_for_picking(); -#endif // ENABLE_RAYCAST_PICKING #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING _render_bed_for_picking(camera->get_view_matrix(), camera->get_projection_matrix(), !camera->is_looking_downward()); -#else - const Camera& camera = wxGetApp().plater()->get_camera(); - _render_bed_for_picking(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward()); -#endif // ENABLE_RAYCAST_PICKING #else _render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward()); #endif // ENABLE_LEGACY_OPENGL_REMOVAL @@ -5799,20 +5661,10 @@ void GLCanvas3D::_rectangular_selection_picking_pass() if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); -#if ENABLE_RAYCAST_PICKING const size_t px_count = width * height; const size_t left = use_framebuffer ? 0 : (size_t)m_rectangle_selection.get_left(); const size_t top = use_framebuffer ? 0 : (size_t)get_canvas_size().get_height() - (size_t)m_rectangle_selection.get_top(); -#else - int width = std::max((int)m_rectangle_selection.get_width(), 1); - int height = std::max((int)m_rectangle_selection.get_height(), 1); - int px_count = width * height; - - int left = (int)m_rectangle_selection.get_left(); - int top = get_canvas_size().get_height() - (int)m_rectangle_selection.get_top(); - if (left >= 0 && top >= 0) { -#endif // ENABLE_RAYCAST_PICKING #define USE_PARALLEL 1 #if USE_PARALLEL struct Pixel @@ -5846,15 +5698,13 @@ void GLCanvas3D::_rectangular_selection_picking_pass() std::vector frame(4 * px_count); glsafe(::glReadPixels(left, top, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)frame.data())); - for (int i = 0; i < px_count; ++i) - { + for (int i = 0; i < px_count; ++i) { int px_id = 4 * i; int volume_id = frame[px_id] + (frame[px_id + 1] << 8) + (frame[px_id + 2] << 16); if (0 <= volume_id && volume_id < (int)m_volumes.volumes.size()) idxs.insert(volume_id); } #endif // USE_PARALLEL -#if ENABLE_RAYCAST_PICKING if (camera != &main_camera) main_camera.apply_viewport(); @@ -5875,9 +5725,6 @@ void GLCanvas3D::_rectangular_selection_picking_pass() if (render_tex != 0) glsafe(::glDeleteTextures(1, &render_tex)); -#else - } -#endif // ENABLE_RAYCAST_PICKING } m_hover_volume_idxs.assign(idxs.begin(), idxs.end()); @@ -6280,11 +6127,7 @@ void GLCanvas3D::_render_overlays() #endif // !ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_RAYCAST_PICKING void GLCanvas3D::_render_volumes_for_picking(const Camera& camera) const -#else -void GLCanvas3D::_render_volumes_for_picking() const -#endif // ENABLE_RAYCAST_PICKING { #if ENABLE_LEGACY_OPENGL_REMOVAL GLShaderProgram* shader = wxGetApp().get_shader("flat_clip"); @@ -6300,11 +6143,7 @@ void GLCanvas3D::_render_volumes_for_picking() const glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING const Transform3d& view_matrix = camera.get_view_matrix(); -#else - const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix(); -#endif // ENABLE_RAYCAST_PICKING for (size_t type = 0; type < 2; ++ type) { GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix); for (const GLVolumeWithIdAndZ& volume : to_render) @@ -6316,12 +6155,7 @@ void GLCanvas3D::_render_volumes_for_picking() const #if ENABLE_LEGACY_OPENGL_REMOVAL volume.first->model.set_color(picking_decode(id)); shader->start_using(); -#if ENABLE_RAYCAST_PICKING shader->set_uniform("view_model_matrix", view_matrix * volume.first->world_matrix()); -#else - const Camera& camera = wxGetApp().plater()->get_camera(); - shader->set_uniform("view_model_matrix", camera.get_view_matrix() * volume.first->world_matrix()); -#endif // ENABLE_RAYCAST_PICKING shader->set_uniform("projection_matrix", camera.get_projection_matrix()); shader->set_uniform("volume_world_matrix", volume.first->world_matrix()); shader->set_uniform("z_range", m_volumes.get_z_range()); @@ -6889,7 +6723,6 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) if (m_canvas == nullptr) return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); -#if ENABLE_RAYCAST_PICKING if (z == nullptr) { const SceneRaycaster::HitResult hit = m_scene_raycaster.hit(mouse_pos.cast(), wxGetApp().plater()->get_camera(), nullptr); return hit.is_valid() ? hit.position.cast() : _mouse_to_bed_3d(mouse_pos); @@ -6901,23 +6734,6 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) igl::unproject(Vec3d(mouse_pos.x(), viewport[3] - mouse_pos.y(), *z), camera.get_view_matrix().matrix(), camera.get_projection_matrix().matrix(), viewport, out); return out; } -#else - const Camera& camera = wxGetApp().plater()->get_camera(); - const Matrix4d modelview = camera.get_view_matrix().matrix(); - const Matrix4d projection = camera.get_projection_matrix().matrix(); - const Vec4i viewport(camera.get_viewport().data()); - - const int y = viewport[3] - mouse_pos.y(); - float mouse_z; - if (z == nullptr) - glsafe(::glReadPixels(mouse_pos.x(), y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, (void*)&mouse_z)); - else - mouse_z = *z; - - Vec3d out; - igl::unproject(Vec3d(mouse_pos.x(), y, mouse_z), modelview, projection, viewport, out); - return out; -#endif // ENABLE_RAYCAST_PICKING } Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a519a26a19..b24a15bbef 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -16,9 +16,7 @@ #include "libslic3r/GCode/GCodeProcessor.hpp" #include "GCodeViewer.hpp" #include "Camera.hpp" -#if ENABLE_RAYCAST_PICKING #include "SceneRaycaster.hpp" -#endif // ENABLE_RAYCAST_PICKING #include "GUI_Utils.hpp" #include "libslic3r/Slicing.hpp" @@ -483,9 +481,7 @@ public: private: wxGLCanvas* m_canvas; wxGLContext* m_context; -#if ENABLE_RAYCAST_PICKING SceneRaycaster m_scene_raycaster; -#endif // ENABLE_RAYCAST_PICKING Bed3D &m_bed; #if ENABLE_RETINA_GL std::unique_ptr m_retina_helper; @@ -669,7 +665,6 @@ public: bool init(); void post_event(wxEvent &&event); -#if ENABLE_RAYCAST_PICKING std::shared_ptr add_raycaster_for_picking(SceneRaycaster::EType type, int id, const MeshRaycaster& raycaster, const Transform3d& trafo = Transform3d::Identity(), bool use_back_faces = false) { return m_scene_raycaster.add_raycaster(type, id, raycaster, trafo, use_back_faces); @@ -688,7 +683,6 @@ public: void set_raycaster_gizmos_on_top(bool value) { m_scene_raycaster.set_gizmos_on_top(value); } -#endif // ENABLE_RAYCAST_PICKING void set_as_dirty(); void requires_check_outside_state() { m_requires_check_outside_state = true; } @@ -1008,11 +1002,7 @@ private: #endif // ENABLE_RENDER_SELECTION_CENTER void _check_and_update_toolbar_icon_scale(); void _render_overlays(); -#if ENABLE_RAYCAST_PICKING void _render_volumes_for_picking(const Camera& camera) const; -#else - void _render_volumes_for_picking() const; -#endif // ENABLE_RAYCAST_PICKING void _render_current_gizmo() const; void _render_gizmos_overlay(); void _render_main_toolbar(); diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index a2c93184b8..d4b4741175 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -30,21 +30,10 @@ namespace GUI { m_end_corner = mouse_position; } -#if ENABLE_RAYCAST_PICKING std::vector GLSelectionRectangle::contains(const std::vector& points) const -#else - std::vector GLSelectionRectangle::stop_dragging(const GLCanvas3D& canvas, const std::vector& points) -#endif // ENABLE_RAYCAST_PICKING { std::vector out; -#if !ENABLE_RAYCAST_PICKING - if (!is_dragging()) - return out; - - m_state = EState::Off; -#endif // !ENABLE_RAYCAST_PICKING - // bounding box created from the rectangle corners - will take care of order of the corners const BoundingBox rectangle(Points{ Point(m_start_corner.cast()), Point(m_end_corner.cast()) }); diff --git a/src/slic3r/GUI/GLSelectionRectangle.hpp b/src/slic3r/GUI/GLSelectionRectangle.hpp index 16eab222ae..ac8abb6aae 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.hpp +++ b/src/slic3r/GUI/GLSelectionRectangle.hpp @@ -26,15 +26,9 @@ public: // To be called on mouse move. void dragging(const Vec2d& mouse_position); -#if ENABLE_RAYCAST_PICKING // Given a vector of points in world coordinates, the function returns indices of those // that are in the rectangle. std::vector contains(const std::vector& points) const; -#else - // Given a vector of points in world coordinates, the function returns indices of those - // that are in the rectangle. It then disables the rectangle. - std::vector stop_dragging(const GLCanvas3D& canvas, const std::vector& points); -#endif // ENABLE_RAYCAST_PICKING // Disables the rectangle. void stop_dragging(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index f4200f8343..a3829fc219 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -18,29 +18,16 @@ const float GLGizmoBase::Grabber::SizeFactor = 0.05f; const float GLGizmoBase::Grabber::MinHalfSize = 1.5f; const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f; -#if ENABLE_RAYCAST_PICKING PickingModel GLGizmoBase::Grabber::s_cube; PickingModel GLGizmoBase::Grabber::s_cone; -#else -GLModel GLGizmoBase::Grabber::s_cube; -GLModel GLGizmoBase::Grabber::s_cone; -#endif // ENABLE_RAYCAST_PICKING GLGizmoBase::Grabber::~Grabber() { -#if ENABLE_RAYCAST_PICKING if (s_cube.model.is_initialized()) s_cube.model.reset(); if (s_cone.model.is_initialized()) s_cone.model.reset(); -#else - if (s_cube.is_initialized()) - s_cube.reset(); - - if (s_cone.is_initialized()) - s_cone.reset(); -#endif // ENABLE_RAYCAST_PICKING } float GLGizmoBase::Grabber::get_half_size(float size) const @@ -53,7 +40,6 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const return get_half_size(size) * DraggingScaleFactor; } -#if ENABLE_RAYCAST_PICKING void GLGizmoBase::Grabber::register_raycasters_for_picking(int id) { picking_id = id; @@ -66,13 +52,8 @@ void GLGizmoBase::Grabber::unregister_raycasters_for_picking() picking_id = -1; raycasters = { nullptr }; } -#endif // ENABLE_RAYCAST_PICKING -#if ENABLE_RAYCAST_PICKING void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color) -#else -void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking) -#endif // ENABLE_RAYCAST_PICKING { #if ENABLE_LEGACY_OPENGL_REMOVAL GLShaderProgram* shader = wxGetApp().get_current_shader(); @@ -80,69 +61,41 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo return; #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING if (!s_cube.model.is_initialized()) { -#else - if (!s_cube.is_initialized()) { -#endif // ENABLE_RAYCAST_PICKING // This cannot be done in constructor, OpenGL is not yet // initialized at that point (on Linux at least). indexed_triangle_set its = its_make_cube(1.0, 1.0, 1.0); its_translate(its, -0.5f * Vec3f::Ones()); #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING s_cube.model.init_from(its); s_cube.mesh_raycaster = std::make_unique(std::make_shared(std::move(its))); -#else - s_cube.init_from(its); -#endif // ENABLE_RAYCAST_PICKING #else s_cube.init_from(its, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } }); #endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_RAYCAST_PICKING if (!s_cone.model.is_initialized()) { indexed_triangle_set its = its_make_cone(0.375, 1.5, double(PI) / 18.0); s_cone.model.init_from(its); s_cone.mesh_raycaster = std::make_unique(std::make_shared(std::move(its))); } -#else - if (!s_cone.is_initialized()) - s_cone.init_from(its_make_cone(0.375, 1.5, double(PI) / 18.0)); -#endif // ENABLE_RAYCAST_PICKING const float half_size = dragging ? get_dragging_half_size(size) : get_half_size(size); #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING s_cube.model.set_color(render_color); s_cone.model.set_color(render_color); -#else - s_cube.set_color(render_color); - s_cone.set_color(render_color); -#endif // ENABLE_RAYCAST_PICKING const Camera& camera = wxGetApp().plater()->get_camera(); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); -#if ENABLE_RAYCAST_PICKING const Transform3d& view_matrix = camera.get_view_matrix(); const Matrix3d view_matrix_no_offset = view_matrix.matrix().block(0, 0, 3, 3); std::vector elements_matrices(GRABBER_ELEMENTS_MAX_COUNT, Transform3d::Identity()); elements_matrices[0] = matrix * Geometry::translation_transform(center) * Geometry::rotation_transform(angles) * Geometry::scale_transform(2.0 * half_size); Transform3d view_model_matrix = view_matrix * elements_matrices[0]; -#else - const Transform3d& view_matrix = camera.get_view_matrix(); - const Transform3d model_matrix = matrix * Geometry::translation_transform(center) * Geometry::rotation_transform(angles) * Geometry::scale_transform(2.0 * half_size); - const Transform3d view_model_matrix = view_matrix * model_matrix; -#endif // ENABLE_RAYCAST_PICKING shader->set_uniform("view_model_matrix", view_model_matrix); -#if ENABLE_RAYCAST_PICKING Matrix3d view_normal_matrix = view_matrix_no_offset * elements_matrices[0].matrix().block(0, 0, 3, 3).inverse().transpose(); -#else - const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); -#endif // ENABLE_RAYCAST_PICKING shader->set_uniform("view_normal_matrix", view_normal_matrix); #else s_cube.set_color(-1, render_color); @@ -154,7 +107,6 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0)); glsafe(::glScaled(2.0 * half_size, 2.0 * half_size, 2.0 * half_size)); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING s_cube.model.render(); auto render_extension = [&view_matrix, &view_matrix_no_offset, shader](const Transform3d& matrix) { @@ -164,64 +116,31 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo shader->set_uniform("view_normal_matrix", view_normal_matrix); s_cone.model.render(); }; -#else - s_cube.render(); -#endif // ENABLE_RAYCAST_PICKING #if ENABLE_LEGACY_OPENGL_REMOVAL if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosX)) != 0) { -#if ENABLE_RAYCAST_PICKING elements_matrices[1] = elements_matrices[0] * Geometry::translation_transform(Vec3d::UnitX()) * Geometry::rotation_transform({ 0.0, 0.5 * double(PI), 0.0 }); render_extension(elements_matrices[1]); -#else - shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::translation_transform(Vec3d::UnitX()) * Geometry::rotation_transform({ 0.0, 0.5 * double(PI), 0.0 })); - s_cone.render(); -#endif // ENABLE_RAYCAST_PICKING } if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegX)) != 0) { -#if ENABLE_RAYCAST_PICKING elements_matrices[2] = elements_matrices[0] * Geometry::translation_transform(-Vec3d::UnitX()) * Geometry::rotation_transform({ 0.0, -0.5 * double(PI), 0.0 }); render_extension(elements_matrices[2]); -#else - shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::translation_transform(-Vec3d::UnitX()) * Geometry::rotation_transform({ 0.0, -0.5 * double(PI), 0.0 })); - s_cone.render(); -#endif // ENABLE_RAYCAST_PICKING } if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosY)) != 0) { -#if ENABLE_RAYCAST_PICKING elements_matrices[3] = elements_matrices[0] * Geometry::translation_transform(Vec3d::UnitY()) * Geometry::rotation_transform({ -0.5 * double(PI), 0.0, 0.0 }); render_extension(elements_matrices[3]); -#else - shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::translation_transform(Vec3d::UnitY()) * Geometry::rotation_transform({ -0.5 * double(PI), 0.0, 0.0 })); - s_cone.render(); -#endif // ENABLE_RAYCAST_PICKING } if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegY)) != 0) { -#if ENABLE_RAYCAST_PICKING elements_matrices[4] = elements_matrices[0] * Geometry::translation_transform(-Vec3d::UnitY()) * Geometry::rotation_transform({ 0.5 * double(PI), 0.0, 0.0 }); render_extension(elements_matrices[4]); -#else - shader->set_uniform("view_model_matrix", view_model_matrix* Geometry::translation_transform(-Vec3d::UnitY())* Geometry::rotation_transform({ 0.5 * double(PI), 0.0, 0.0 })); - s_cone.render(); -#endif // ENABLE_RAYCAST_PICKING } if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosZ)) != 0) { -#if ENABLE_RAYCAST_PICKING elements_matrices[5] = elements_matrices[0] * Geometry::translation_transform(Vec3d::UnitZ()); render_extension(elements_matrices[5]); -#else - shader->set_uniform("view_model_matrix", view_model_matrix* Geometry::translation_transform(Vec3d::UnitZ())); - s_cone.render(); -#endif // ENABLE_RAYCAST_PICKING } if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegZ)) != 0) { -#if ENABLE_RAYCAST_PICKING elements_matrices[6] = elements_matrices[0] * Geometry::translation_transform(-Vec3d::UnitZ()) * Geometry::rotation_transform({ double(PI), 0.0, 0.0 }); - render_extension(elements_matrices[6]); -#else - shader->set_uniform("view_model_matrix", view_model_matrix* Geometry::translation_transform(-Vec3d::UnitZ())* Geometry::rotation_transform({ double(PI), 0.0, 0.0 })); - s_cone.render(); -#endif // ENABLE_RAYCAST_PICKING + render_extension(elements_matrices[6]); } #else if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosX)) != 0) { @@ -270,7 +189,6 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo glsafe(::glPopMatrix()); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING if (raycasters[0] == nullptr) { GLCanvas3D& canvas = *wxGetApp().plater()->canvas3D(); raycasters[0] = canvas.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, picking_id, *s_cube.mesh_raycaster, elements_matrices[0]); @@ -293,7 +211,6 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo raycasters[i]->set_transform(elements_matrices[i]); } } -#endif // ENABLE_RAYCAST_PICKING } GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) @@ -327,7 +244,6 @@ bool GLGizmoBase::update_items_state() return res; } -#if ENABLE_RAYCAST_PICKING void GLGizmoBase::register_grabbers_for_picking() { for (size_t i = 0; i < m_grabbers.size(); ++i) { @@ -341,16 +257,6 @@ void GLGizmoBase::unregister_grabbers_for_picking() m_grabbers[i].unregister_raycasters_for_picking(); } } -#else -ColorRGBA GLGizmoBase::picking_color_component(unsigned int id) const -{ - id = BASE_ID - id; - if (m_group_id > -1) - id -= m_group_id; - - return picking_decode(id); -} -#endif // ENABLE_RAYCAST_PICKING void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const { @@ -371,29 +277,6 @@ void GLGizmoBase::render_grabbers(float size) const shader->stop_using(); } -#if !ENABLE_RAYCAST_PICKING -void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const -{ -#if ENABLE_LEGACY_OPENGL_REMOVAL - GLShaderProgram* shader = wxGetApp().get_shader("flat"); - if (shader != nullptr) { - shader->start_using(); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL - const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0); - - for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) { - if (m_grabbers[i].enabled) { - m_grabbers[i].color = picking_color_component(i); - m_grabbers[i].render_for_picking(mean_size); - } - } -#if ENABLE_LEGACY_OPENGL_REMOVAL - shader->stop_using(); - } -#endif // ENABLE_LEGACY_OPENGL_REMOVAL -} -#endif // !ENABLE_RAYCAST_PICKING - // help function to process grabbers // call start_dragging, stop_dragging, on_dragging bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 1d134948d4..3c3f5c287e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -6,10 +6,8 @@ #include "slic3r/GUI/I18N.hpp" #include "slic3r/GUI/GLModel.hpp" -#if ENABLE_RAYCAST_PICKING #include "slic3r/GUI/MeshUtils.hpp" #include "slic3r/GUI/SceneRaycaster.hpp" -#endif // ENABLE_RAYCAST_PICKING #include @@ -73,44 +71,26 @@ protected: #endif // ENABLE_LEGACY_OPENGL_REMOVAL ColorRGBA color{ ColorRGBA::WHITE() }; EGrabberExtension extensions{ EGrabberExtension::None }; -#if ENABLE_RAYCAST_PICKING // the picking id shared by all the elements int picking_id{ -1 }; std::array, GRABBER_ELEMENTS_MAX_COUNT> raycasters = { nullptr }; -#endif // ENABLE_RAYCAST_PICKING Grabber() = default; ~Grabber(); -#if ENABLE_RAYCAST_PICKING void render(bool hover, float size) { render(size, hover ? complementary(color) : color); } -#else - void render(bool hover, float size) { render(size, hover ? complementary(color) : color, false); } - void render_for_picking(float size) { render(size, color, true); } -#endif // ENABLE_RAYCAST_PICKING float get_half_size(float size) const; float get_dragging_half_size(float size) const; -#if ENABLE_RAYCAST_PICKING void register_raycasters_for_picking(int id); void unregister_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING private: -#if ENABLE_RAYCAST_PICKING void render(float size, const ColorRGBA& render_color); -#else - void render(float size, const ColorRGBA& render_color, bool picking); -#endif // ENABLE_RAYCAST_PICKING -#if ENABLE_RAYCAST_PICKING static PickingModel s_cube; static PickingModel s_cone; -#else - static GLModel s_cube; - static GLModel s_cone; -#endif // ENABLE_RAYCAST_PICKING }; public: @@ -186,9 +166,6 @@ public: bool update_items_state(); void render() { on_render(); } -#if !ENABLE_RAYCAST_PICKING - void render_for_picking() { on_render_for_picking(); } -#endif // !ENABLE_RAYCAST_PICKING void render_input_window(float x, float y, float bottom_limit); /// @@ -210,10 +187,8 @@ public: /// Return True when use the information and don't want to propagate it otherwise False. virtual bool on_mouse(const wxMouseEvent &mouse_event) { return false; } -#if ENABLE_RAYCAST_PICKING void register_raycasters_for_picking() { register_grabbers_for_picking(); on_register_raycasters_for_picking(); } void unregister_raycasters_for_picking() { unregister_grabbers_for_picking(); on_unregister_raycasters_for_picking(); } -#endif // ENABLE_RAYCAST_PICKING virtual bool is_in_editing_mode() const { return false; } virtual bool is_selection_rectangle_dragging() const { return false; } @@ -237,27 +212,15 @@ protected: virtual void on_dragging(const UpdateData& data) {} virtual void on_render() = 0; -#if !ENABLE_RAYCAST_PICKING - virtual void on_render_for_picking() = 0; -#endif // !ENABLE_RAYCAST_PICKING virtual void on_render_input_window(float x, float y, float bottom_limit) {} -#if ENABLE_RAYCAST_PICKING void register_grabbers_for_picking(); void unregister_grabbers_for_picking(); virtual void on_register_raycasters_for_picking() {} virtual void on_unregister_raycasters_for_picking() {} -#else - // Returns the picking color for the given id, based on the BASE_ID constant - // No check is made for clashing with other picking color (i.e. GLVolumes) - ColorRGBA picking_color_component(unsigned int id) const; -#endif // ENABLE_RAYCAST_PICKING void render_grabbers(const BoundingBoxf3& box) const; void render_grabbers(float size) const; -#if !ENABLE_RAYCAST_PICKING - void render_grabbers_for_picking(const BoundingBoxf3& box) const; -#endif // !ENABLE_RAYCAST_PICKING std::string format(float value, unsigned int decimals) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 7a853e7187..542aceead0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -600,18 +600,12 @@ void GLGizmoEmboss::on_render() { } } -#if ENABLE_RAYCAST_PICKING void GLGizmoEmboss::on_register_raycasters_for_picking(){ m_rotate_gizmo.register_raycasters_for_picking(); } void GLGizmoEmboss::on_unregister_raycasters_for_picking(){ m_rotate_gizmo.unregister_raycasters_for_picking(); } -#else // !ENABLE_RAYCAST_PICKING -void GLGizmoEmboss::on_render_for_picking() { - m_rotate_gizmo.render_for_picking(); -} -#endif // ENABLE_RAYCAST_PICKING #ifdef SHOW_FINE_POSITION // draw suggested position of window diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 092041e96e..fe3ccf73bc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -56,12 +56,8 @@ protected: bool on_init() override; std::string on_get_name() const override; void on_render() override; -#if ENABLE_RAYCAST_PICKING virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; -#else // !ENABLE_RAYCAST_PICKING - void on_render_for_picking() override; -#endif // ENABLE_RAYCAST_PICKING void on_render_input_window(float x, float y, float bottom_limit) override; bool on_is_activable() const override { return true; } bool on_is_selectable() const override { return false; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index ddabec7e61..463eb3182b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -131,14 +131,9 @@ void GLGizmoFlatten::on_render() update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_planes_casters[i]->set_transform(model_matrix); m_planes[i].vbo.model.set_color(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR : DEFAULT_PLANE_COLOR); m_planes[i].vbo.model.render(); -#else - m_planes[i].vbo.set_color(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR : DEFAULT_PLANE_COLOR); - m_planes[i].vbo.render(); -#endif // ENABLE_RAYCAST_PICKING #else glsafe(::glColor4fv(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR.data() : DEFAULT_PLANE_COLOR.data())); if (m_planes[i].vbo.has_VBOs()) @@ -158,7 +153,6 @@ void GLGizmoFlatten::on_render() #endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_RAYCAST_PICKING void GLGizmoFlatten::on_register_raycasters_for_picking() { // the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account @@ -183,66 +177,12 @@ void GLGizmoFlatten::on_unregister_raycasters_for_picking() m_parent.set_raycaster_gizmos_on_top(false); m_planes_casters.clear(); } -#else -void GLGizmoFlatten::on_render_for_picking() -{ - const Selection& selection = m_parent.get_selection(); - -#if ENABLE_LEGACY_OPENGL_REMOVAL - GLShaderProgram* shader = wxGetApp().get_shader("flat"); - if (shader == nullptr) - return; - - shader->start_using(); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL - - glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glDisable(GL_BLEND)); - - if (selection.is_single_full_instance() && !wxGetKeyState(WXK_CONTROL)) { - const Transform3d& m = selection.get_first_volume()->get_instance_transformation().get_matrix(); -#if ENABLE_LEGACY_OPENGL_REMOVAL - const Camera& camera = wxGetApp().plater()->get_camera(); - const Transform3d view_model_matrix = camera.get_view_matrix() * - Geometry::translation_transform(selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) * m; - - shader->set_uniform("view_model_matrix", view_model_matrix); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); -#else - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.f, 0.f, selection.get_first_volume()->get_sla_shift_z())); - glsafe(::glMultMatrixd(m.data())); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL - if (this->is_plane_update_necessary()) - update_planes(); - for (int i = 0; i < (int)m_planes.size(); ++i) { -#if ENABLE_LEGACY_OPENGL_REMOVAL - m_planes[i].vbo.set_color(picking_color_component(i)); -#else - glsafe(::glColor4fv(picking_color_component(i).data())); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL - m_planes[i].vbo.render(); - } -#if !ENABLE_LEGACY_OPENGL_REMOVAL - glsafe(::glPopMatrix()); -#endif // !ENABLE_LEGACY_OPENGL_REMOVAL - } - - glsafe(::glEnable(GL_CULL_FACE)); - -#if ENABLE_LEGACY_OPENGL_REMOVAL - shader->stop_using(); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL -} -#endif // ENABLE_RAYCAST_PICKING void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object) { if (model_object != m_old_model_object) { m_planes.clear(); -#if ENABLE_RAYCAST_PICKING on_unregister_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING } } @@ -259,9 +199,7 @@ void GLGizmoFlatten::update_planes() } ch = ch.convex_hull_3d(); m_planes.clear(); -#if ENABLE_RAYCAST_PICKING on_unregister_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING #if ENABLE_WORLD_COORDINATE const Transform3d inst_matrix = mo->instances.front()->get_matrix_no_offset(); #else @@ -458,7 +396,6 @@ void GLGizmoFlatten::update_planes() // the vertices in order, so triangulation is trivial. for (auto& plane : m_planes) { #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING indexed_triangle_set its; its.vertices.reserve(plane.vertices.size()); its.indices.reserve(plane.vertices.size() / 3); @@ -470,18 +407,6 @@ void GLGizmoFlatten::update_planes() } plane.vbo.model.init_from(its); plane.vbo.mesh_raycaster = std::make_unique(std::make_shared(std::move(its))); -#else - GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::TriangleFan, GLModel::Geometry::EVertexLayout::P3N3 }; - init_data.reserve_vertices(plane.vertices.size()); - init_data.reserve_indices(plane.vertices.size()); - // vertices + indices - for (size_t i = 0; i < plane.vertices.size(); ++i) { - init_data.add_vertex((Vec3f)plane.vertices[i].cast(), (Vec3f)plane.normal.cast()); - init_data.add_index((unsigned int)i); - } - plane.vbo.init_from(std::move(init_data)); -#endif // ENABLE_RAYCAST_PICKING #else plane.vbo.reserve(plane.vertices.size()); for (const auto& vert : plane.vertices) @@ -496,12 +421,9 @@ void GLGizmoFlatten::update_planes() plane.vertices.shrink_to_fit(); } -#if ENABLE_RAYCAST_PICKING on_register_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING } - bool GLGizmoFlatten::is_plane_update_necessary() const { const ModelObject* mo = m_c->selection_info()->model_object(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp index b4e47d3985..900a3361db 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp @@ -4,9 +4,7 @@ #include "GLGizmoBase.hpp" #if ENABLE_LEGACY_OPENGL_REMOVAL #include "slic3r/GUI/GLModel.hpp" -#if ENABLE_RAYCAST_PICKING #include "slic3r/GUI/MeshUtils.hpp" -#endif // ENABLE_RAYCAST_PICKING #else #include "slic3r/GUI/3DScene.hpp" #endif // ENABLE_LEGACY_OPENGL_REMOVAL @@ -30,19 +28,13 @@ private: struct PlaneData { std::vector vertices; // should be in fact local in update_planes() #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING PickingModel vbo; -#else - GLModel vbo; -#endif // ENABLE_RAYCAST_PICKING #else GLIndexedVertexArray vbo; #endif // ENABLE_LEGACY_OPENGL_REMOVAL Vec3d normal; float area; -#if ENABLE_RAYCAST_PICKING int picking_id{ -1 }; -#endif // ENABLE_RAYCAST_PICKING }; // This holds information to decide whether recalculation is necessary: @@ -52,9 +44,7 @@ private: Vec3d m_first_instance_mirror; std::vector m_planes; -#if ENABLE_RAYCAST_PICKING std::vector> m_planes_casters; -#endif // ENABLE_RAYCAST_PICKING bool m_mouse_left_down = false; // for detection left_up of this gizmo const ModelObject* m_old_model_object = nullptr; @@ -79,12 +69,8 @@ protected: std::string on_get_name() const override; bool on_is_activable() const override; void on_render() override; -#if ENABLE_RAYCAST_PICKING virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; -#else - void on_render_for_picking() override; -#endif // ENABLE_RAYCAST_PICKING void on_set_state() override; CommonGizmosDataID on_get_requirements() const override; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 51ea56c821..be04fb92c6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -55,12 +55,10 @@ void GLGizmoHollow::data_changed() } if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) m_holes_in_drilled_mesh = mo->sla_drain_holes; -#if ENABLE_RAYCAST_PICKING if (m_raycasters.empty()) on_register_raycasters_for_picking(); else update_raycasters_for_picking_transform(); -#endif // ENABLE_RAYCAST_PICKING } } @@ -68,11 +66,6 @@ void GLGizmoHollow::data_changed() void GLGizmoHollow::on_render() { -#if !ENABLE_RAYCAST_PICKING - if (!m_cylinder.is_initialized()) - m_cylinder.init_from(its_make_cylinder(1.0, 1.0)); -#endif // !ENABLE_RAYCAST_PICKING - const Selection& selection = m_parent.get_selection(); const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info(); @@ -88,11 +81,7 @@ void GLGizmoHollow::on_render() glsafe(::glEnable(GL_DEPTH_TEST)); if (selection.is_from_single_instance()) -#if ENABLE_RAYCAST_PICKING render_points(selection); -#else - render_points(selection, false); -#endif // ENABLE_RAYCAST_PICKING m_selection_rectangle.render(m_parent); m_c->object_clipper()->render_cut(); @@ -101,7 +90,6 @@ void GLGizmoHollow::on_render() glsafe(::glDisable(GL_BLEND)); } -#if ENABLE_RAYCAST_PICKING void GLGizmoHollow::on_register_raycasters_for_picking() { assert(m_raycasters.empty()); @@ -126,27 +114,11 @@ void GLGizmoHollow::on_unregister_raycasters_for_picking() m_raycasters.clear(); set_sla_auxiliary_volumes_picking_state(true); } -#else -void GLGizmoHollow::on_render_for_picking() -{ - const Selection& selection = m_parent.get_selection(); - glsafe(::glEnable(GL_DEPTH_TEST)); - render_points(selection, true); -} -#endif // ENABLE_RAYCAST_PICKING -#if ENABLE_RAYCAST_PICKING void GLGizmoHollow::render_points(const Selection& selection) -#else -void GLGizmoHollow::render_points(const Selection& selection, bool picking) -#endif // ENABLE_RAYCAST_PICKING { #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#else - GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat") : wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_RAYCAST_PICKING if (shader == nullptr) return; @@ -188,41 +160,24 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) const sla::DrainHole& drain_hole = drain_holes[i]; const bool point_selected = m_selected[i]; -#if ENABLE_RAYCAST_PICKING const bool clipped = is_mesh_point_clipped(drain_hole.pos.cast()); m_raycasters[i]->set_active(!clipped); if (clipped) continue; -#else - if (is_mesh_point_clipped(drain_hole.pos.cast())) - continue; -#endif // ENABLE_RAYCAST_PICKING // First decide about the color of the point. -#if !ENABLE_RAYCAST_PICKING - if (picking) - render_color = picking_color_component(i); - else { -#endif // !ENABLE_RAYCAST_PICKING - if (size_t(m_hover_id) == i) - render_color = ColorRGBA::CYAN(); - else if (m_c->hollowed_mesh() && - i < m_c->hollowed_mesh()->get_drainholes().size() && - m_c->hollowed_mesh()->get_drainholes()[i].failed) { - render_color = { 1.0f, 0.0f, 0.0f, 0.5f }; - } - else - render_color = point_selected ? ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f) : ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f); -#if !ENABLE_RAYCAST_PICKING - } -#endif // !ENABLE_RAYCAST_PICKING + if (size_t(m_hover_id) == i) + render_color = ColorRGBA::CYAN(); + else if (m_c->hollowed_mesh() && + i < m_c->hollowed_mesh()->get_drainholes().size() && + m_c->hollowed_mesh()->get_drainholes()[i].failed) { + render_color = { 1.0f, 0.0f, 0.0f, 0.5f }; + } + else + render_color = point_selected ? ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f) : ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f); #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_cylinder.model.set_color(render_color); -#else - m_cylinder.set_color(render_color); -#endif // ENABLE_RAYCAST_PICKING // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. const Transform3d hole_matrix = Geometry::translation_transform(drain_hole.pos.cast()) * instance_scaling_matrix_inverse; #else @@ -251,11 +206,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) glsafe(::glTranslated(0., 0., -drain_hole.height)); glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_cylinder.model.render(); -#else - m_cylinder.render(); -#endif // ENABLE_RAYCAST_PICKING if (vol->is_left_handed()) glsafe(::glFrontFace(GL_CCW)); @@ -382,10 +333,8 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos assert(m_selected.size() == mo->sla_drain_holes.size()); m_parent.set_as_dirty(); m_wait_for_up_event = true; -#if ENABLE_RAYCAST_PICKING on_unregister_raycasters_for_picking(); on_register_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING } else return false; @@ -410,12 +359,8 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos // Now ask the rectangle which of the points are inside. std::vector points_inside; -#if ENABLE_RAYCAST_PICKING std::vector points_idxs = m_selection_rectangle.contains(points); m_selection_rectangle.stop_dragging(); -#else - std::vector points_idxs = m_selection_rectangle.stop_dragging(m_parent, points); -#endif // ENABLE_RAYCAST_PICKING for (size_t idx : points_idxs) points_inside.push_back(points[idx].cast()); @@ -509,10 +454,8 @@ void GLGizmoHollow::delete_selected_points() } } -#if ENABLE_RAYCAST_PICKING on_unregister_raycasters_for_picking(); on_register_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING select_point(NoPoints); } @@ -588,7 +531,6 @@ void GLGizmoHollow::hollow_mesh(bool postpone_error_messages) }); } -#if ENABLE_RAYCAST_PICKING void GLGizmoHollow::set_sla_auxiliary_volumes_picking_state(bool state) { std::vector>* raycasters = m_parent.get_raycasters_for_picking(SceneRaycaster::EType::Volume); @@ -630,7 +572,6 @@ void GLGizmoHollow::update_raycasters_for_picking_transform() } } } -#endif // ENABLE_RAYCAST_PICKING std::vector> GLGizmoHollow::get_config_options(const std::vector& keys) const @@ -900,11 +841,9 @@ RENDER_AGAIN: bool show_sups = m_c->instances_hider()->are_supports_shown(); if (m_imgui->checkbox(m_desc["show_supports"], show_sups)) { m_c->instances_hider()->show_supports(show_sups); -#if ENABLE_RAYCAST_PICKING if (show_sups) // ensure supports and pad are disabled from picking even when they are visible set_sla_auxiliary_volumes_picking_state(false); -#endif // ENABLE_RAYCAST_PICKING force_refresh = true; } @@ -1100,7 +1039,6 @@ void GLGizmoHollow::on_set_hover_id() m_hover_id = -1; } -#if ENABLE_RAYCAST_PICKING void GLGizmoHollow::init_cylinder_model() { if (!m_cylinder.model.is_initialized()) { @@ -1109,7 +1047,6 @@ void GLGizmoHollow::init_cylinder_model() m_cylinder.mesh_raycaster = std::make_unique(std::make_shared(std::move(its))); } } -#endif // ENABLE_RAYCAST_PICKING diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index 0fdc3b2db7..ea88c4291a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -46,33 +46,19 @@ public: protected: bool on_init() override; void on_render() override; -#if ENABLE_RAYCAST_PICKING virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; -#else - void on_render_for_picking() override; -#endif // ENABLE_RAYCAST_PICKING private: -#if ENABLE_RAYCAST_PICKING void render_points(const Selection& selection); -#else - void render_points(const Selection& selection, bool picking = false); -#endif // ENABLE_RAYCAST_PICKING void hollow_mesh(bool postpone_error_messages = false); -#if ENABLE_RAYCAST_PICKING void set_sla_auxiliary_volumes_picking_state(bool state); void update_raycasters_for_picking_transform(); -#endif // ENABLE_RAYCAST_PICKING ObjectID m_old_mo_id = -1; -#if ENABLE_RAYCAST_PICKING PickingModel m_cylinder; std::vector> m_raycasters; -#else - GLModel m_cylinder; -#endif // ENABLE_RAYCAST_PICKING float m_new_hole_radius = 2.f; // Size of a new hole. float m_new_hole_height = 6.f; @@ -128,9 +114,7 @@ protected: void on_load(cereal::BinaryInputArchive& ar) override; void on_save(cereal::BinaryOutputArchive& ar) const override; -#if ENABLE_RAYCAST_PICKING void init_cylinder_model(); -#endif // ENABLE_RAYCAST_PICKING }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 23edd6143f..bb5ebfd260 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -362,7 +362,6 @@ void GLGizmoMove3D::on_render() #endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_RAYCAST_PICKING void GLGizmoMove3D::on_register_raycasters_for_picking() { // the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account @@ -373,32 +372,6 @@ void GLGizmoMove3D::on_unregister_raycasters_for_picking() { m_parent.set_raycaster_gizmos_on_top(false); } -#else -void GLGizmoMove3D::on_render_for_picking() -{ - glsafe(::glDisable(GL_DEPTH_TEST)); - -#if ENABLE_WORLD_COORDINATE -#if ENABLE_LEGACY_OPENGL_REMOVAL - const Transform3d base_matrix = local_transform(m_parent.get_selection()); - for (int i = 0; i < 3; ++i) { - m_grabbers[i].matrix = base_matrix; - } -#else - glsafe(::glPushMatrix()); - transform_to_local(m_parent.get_selection()); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL - render_grabbers_for_picking(m_bounding_box); -#if ENABLE_LEGACY_OPENGL_REMOVAL -#else - glsafe(::glPopMatrix()); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#else - const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box(); - render_grabbers_for_picking(box); -#endif // ENABLE_WORLD_COORDINATE -} -#endif // ENABLE_RAYCAST_PICKING double GLGizmoMove3D::calc_projection(const UpdateData& data) const { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index 7a4d82a41c..3a69e86efb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -62,12 +62,8 @@ protected: void on_stop_dragging() override; void on_dragging(const UpdateData& data) override; void on_render() override; -#if ENABLE_RAYCAST_PICKING virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; -#else - void on_render_for_picking() override; -#endif // ENABLE_RAYCAST_PICKING 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 94aca4fdb7..d4261761f6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -138,9 +138,6 @@ private: ObjectID m_old_mo_id; size_t m_old_volumes_size = 0; void on_render() override {} -#if !ENABLE_RAYCAST_PICKING - void on_render_for_picking() override {} -#endif // !ENABLE_RAYCAST_PICKING 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 6c57df7e59..5b39c09291 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -256,33 +256,6 @@ void GLGizmoRotate::on_render() #endif // !ENABLE_LEGACY_OPENGL_REMOVAL } -#if !ENABLE_RAYCAST_PICKING -void GLGizmoRotate::on_render_for_picking() -{ - const Selection& selection = m_parent.get_selection(); - - glsafe(::glDisable(GL_DEPTH_TEST)); - -#if ENABLE_LEGACY_OPENGL_REMOVAL - m_grabbers.front().matrix = local_transform(selection); -#else - glsafe(::glPushMatrix()); - transform_to_local(selection); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL - -#if ENABLE_WORLD_COORDINATE - render_grabbers_for_picking(m_bounding_box); -#else - const BoundingBoxf3& box = selection.get_bounding_box(); - render_grabbers_for_picking(box); -#endif // ENABLE_WORLD_COORDINATE - -#if !ENABLE_LEGACY_OPENGL_REMOVAL - glsafe(::glPopMatrix()); -#endif // !ENABLE_LEGACY_OPENGL_REMOVAL -} -#endif // !ENABLE_RAYCAST_PICKING - #if ENABLE_WORLD_COORDINATE void GLGizmoRotate::init_data_from_selection(const Selection& selection) { @@ -906,7 +879,6 @@ void GLGizmoRotate3D::on_render() m_gizmos[Z].render(); } -#if ENABLE_RAYCAST_PICKING void GLGizmoRotate3D::on_register_raycasters_for_picking() { // the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account @@ -923,7 +895,6 @@ void GLGizmoRotate3D::on_unregister_raycasters_for_picking() } m_parent.set_raycaster_gizmos_on_top(false); } -#endif // ENABLE_RAYCAST_PICKING GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui, State & state, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index cbc0f104b3..d117a12192 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -98,9 +98,6 @@ protected: void on_start_dragging() override; void on_dragging(const UpdateData &data) override; void on_render() override; -#if !ENABLE_RAYCAST_PICKING - void on_render_for_picking() override; -#endif // !ENABLE_RAYCAST_PICKING private: #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -189,16 +186,8 @@ protected: void on_dragging(const UpdateData &data) override; void on_render() override; -#if ENABLE_RAYCAST_PICKING virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; -#else - void on_render_for_picking() override { - for (GLGizmoRotate& g : m_gizmos) { - g.render_for_picking(); - } - } -#endif // ENABLE_RAYCAST_PICKING void on_render_input_window(float x, float y, float bottom_limit) override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 03be5c2f4c..42c74594c7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -650,7 +650,6 @@ void GLGizmoScale3D::on_render() #endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_RAYCAST_PICKING void GLGizmoScale3D::on_register_raycasters_for_picking() { // the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account @@ -661,29 +660,6 @@ void GLGizmoScale3D::on_unregister_raycasters_for_picking() { m_parent.set_raycaster_gizmos_on_top(false); } -#else -void GLGizmoScale3D::on_render_for_picking() -{ - glsafe(::glDisable(GL_DEPTH_TEST)); -#if ENABLE_WORLD_COORDINATE -#if ENABLE_LEGACY_OPENGL_REMOVAL - const Transform3d base_matrix = local_transform(m_parent.get_selection()); - for (int i = 0; i < 10; ++i) { - m_grabbers[i].matrix = base_matrix; - } -#else - glsafe(::glPushMatrix()); - transform_to_local(m_parent.get_selection()); -#endif // ENABLE_LEGACY_OPENGL_REMOVAL - render_grabbers_for_picking(m_bounding_box); -#if !ENABLE_LEGACY_OPENGL_REMOVAL - glsafe(::glPopMatrix()); -#endif // !ENABLE_LEGACY_OPENGL_REMOVAL -#else - render_grabbers_for_picking(m_parent.get_selection().get_bounding_box()); -#endif // ENABLE_WORLD_COORDINATE -} -#endif // !ENABLE_RAYCAST_PICKING #if ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp index d51cec8150..bf55115282 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp @@ -94,12 +94,8 @@ protected: virtual void on_stop_dragging() override; virtual void on_dragging(const UpdateData& data) override; virtual void on_render() override; -#if ENABLE_RAYCAST_PICKING virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; -#else - virtual void on_render_for_picking() override; -#endif // ENABLE_RAYCAST_PICKING private: #if ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.hpp index 8317b45d71..f95aad4953 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.hpp @@ -38,9 +38,6 @@ protected: // must implement virtual bool on_init() override { return true;}; virtual void on_render() override; -#if !ENABLE_RAYCAST_PICKING - virtual void on_render_for_picking() override{}; -#endif // !ENABLE_RAYCAST_PICKING CommonGizmosDataID on_get_requirements() const override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 1646f31c7f..1520a2ef14 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -22,10 +22,8 @@ #include "libslic3r/PresetBundle.hpp" #include "libslic3r/SLAPrint.hpp" -#if ENABLE_RAYCAST_PICKING static const double CONE_RADIUS = 0.25; static const double CONE_HEIGHT = 0.75; -#endif // ENABLE_RAYCAST_PICKING namespace Slic3r { namespace GUI { @@ -51,12 +49,6 @@ bool GLGizmoSlaSupports::on_init() m_desc["clipping_of_view"] = _L("Clipping of view")+ ": "; m_desc["reset_direction"] = _L("Reset direction"); -#if !ENABLE_RAYCAST_PICKING - m_cone.init_from(its_make_cone(1., 1., 2 * PI / 24)); - m_cylinder.init_from(its_make_cylinder(1., 1., 2 * PI / 24.)); - m_sphere.init_from(its_make_sphere(1., (2 * M_PI) / 24.)); -#endif // !ENABLE_RAYCAST_PICKING - return true; } @@ -79,12 +71,10 @@ void GLGizmoSlaSupports::data_changed() if (mo->sla_points_status == sla::PointsStatus::Generating) get_data_from_backend(); -#if ENABLE_RAYCAST_PICKING if (m_raycasters.empty()) on_register_raycasters_for_picking(); else update_raycasters_for_picking_transform(); -#endif // ENABLE_RAYCAST_PICKING } } @@ -92,7 +82,6 @@ void GLGizmoSlaSupports::data_changed() void GLGizmoSlaSupports::on_render() { -#if ENABLE_RAYCAST_PICKING if (!m_sphere.model.is_initialized()) { indexed_triangle_set its = its_make_sphere(1.0, double(PI) / 12.0); m_sphere.model.init_from(its); @@ -103,12 +92,6 @@ void GLGizmoSlaSupports::on_render() m_cone.model.init_from(its); m_cone.mesh_raycaster = std::make_unique(std::make_shared(std::move(its))); } -#else - if (!m_cone.is_initialized()) - m_cone.init_from(its_make_cone(1.0, 1.0, double(PI) / 12.0)); - if (!m_sphere.is_initialized()) - m_sphere.init_from(its_make_sphere(1.0, double(PI) / 12.0)); -#endif // ENABLE_RAYCAST_PICKING if (!m_cylinder.is_initialized()) m_cylinder.init_from(its_make_cylinder(1.0, 1.0, double(PI) / 12.0)); @@ -127,11 +110,7 @@ void GLGizmoSlaSupports::on_render() glsafe(::glEnable(GL_DEPTH_TEST)); if (selection.is_from_single_instance()) -#if ENABLE_RAYCAST_PICKING render_points(selection); -#else - render_points(selection, false); -#endif // ENABLE_RAYCAST_PICKING m_selection_rectangle.render(m_parent); m_c->object_clipper()->render_cut(); @@ -140,7 +119,6 @@ void GLGizmoSlaSupports::on_render() glsafe(::glDisable(GL_BLEND)); } -#if ENABLE_RAYCAST_PICKING void GLGizmoSlaSupports::on_register_raycasters_for_picking() { assert(m_raycasters.empty()); @@ -161,20 +139,8 @@ void GLGizmoSlaSupports::on_unregister_raycasters_for_picking() m_raycasters.clear(); set_sla_auxiliary_volumes_picking_state(true); } -#else -void GLGizmoSlaSupports::on_render_for_picking() -{ - const Selection& selection = m_parent.get_selection(); - //glsafe(::glEnable(GL_DEPTH_TEST)); - render_points(selection, true); -} -#endif // ENABLE_RAYCAST_PICKING -#if ENABLE_RAYCAST_PICKING void GLGizmoSlaSupports::render_points(const Selection& selection) -#else -void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) -#endif // ENABLE_RAYCAST_PICKING { const size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size(); @@ -186,11 +152,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) return; #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#else - GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light"); -#endif // ENABLE_RAYCAST_PICKING if (shader == nullptr) return; @@ -230,7 +192,6 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i]; const bool point_selected = m_editing_mode ? m_editing_cache[i].selected : false; -#if ENABLE_RAYCAST_PICKING const bool clipped = is_mesh_point_clipped(support_point.pos.cast()); if (!m_raycasters.empty()) { m_raycasters[i].first->set_active(!clipped); @@ -238,48 +199,28 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) } if (clipped) continue; -#else - if (is_mesh_point_clipped(support_point.pos.cast())) - continue; -#endif // ENABLE_RAYCAST_PICKING // First decide about the color of the point. -#if !ENABLE_RAYCAST_PICKING - if (picking) - render_color = picking_color_component(i); - else { -#endif // !ENABLE_RAYCAST_PICKING - if (size_t(m_hover_id) == i && m_editing_mode) // ignore hover state unless editing mode is active - render_color = { 0.f, 1.f, 1.f, 1.f }; - else { // neigher hover nor picking - bool supports_new_island = m_lock_unique_islands && support_point.is_new_island; - if (m_editing_mode) { - if (point_selected) - render_color = { 1.f, 0.3f, 0.3f, 1.f}; - else - if (supports_new_island) - render_color = { 0.3f, 0.3f, 1.f, 1.f }; - else - render_color = { 0.7f, 0.7f, 0.7f, 1.f }; - } + if (size_t(m_hover_id) == i && m_editing_mode) // ignore hover state unless editing mode is active + render_color = { 0.f, 1.f, 1.f, 1.f }; + else { // neigher hover nor picking + bool supports_new_island = m_lock_unique_islands && support_point.is_new_island; + if (m_editing_mode) { + if (point_selected) + render_color = { 1.f, 0.3f, 0.3f, 1.f}; else - render_color = { 0.5f, 0.5f, 0.5f, 1.f }; + if (supports_new_island) + render_color = { 0.3f, 0.3f, 1.f, 1.f }; + else + render_color = { 0.7f, 0.7f, 0.7f, 1.f }; } -#if !ENABLE_RAYCAST_PICKING + else + render_color = { 0.5f, 0.5f, 0.5f, 1.f }; } -#endif // !ENABLE_RAYCAST_PICKING #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_cone.model.set_color(render_color); m_sphere.model.set_color(render_color); -#else - m_cone.set_color(render_color); - m_sphere.set_color(render_color); -#endif // ENABLE_RAYCAST_PICKING -#if !ENABLE_RAYCAST_PICKING - if (!picking) -#endif // !ENABLE_RAYCAST_PICKING #else m_cone.set_color(-1, render_color); m_sphere.set_color(-1, render_color); @@ -309,19 +250,10 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) Eigen::Quaterniond q; q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast()); const Eigen::AngleAxisd aa(q); -#if !ENABLE_RAYCAST_PICKING - const double cone_radius = 0.25; // mm - const double cone_height = 0.75; -#endif // !ENABLE_RAYCAST_PICKING #if ENABLE_LEGACY_OPENGL_REMOVAL const Transform3d model_matrix = vol->world_matrix() * support_matrix * Transform3d(aa.toRotationMatrix()) * -#if ENABLE_RAYCAST_PICKING Geometry::translation_transform((CONE_HEIGHT + support_point.head_front_radius * RenderPointScale) * Vec3d::UnitZ()) * Geometry::rotation_transform({ double(PI), 0.0, 0.0 }) * Geometry::scale_transform({ CONE_RADIUS, CONE_RADIUS, CONE_HEIGHT }); -#else - Geometry::translation_transform((cone_height + support_point.head_front_radius * RenderPointScale) * Vec3d::UnitZ()) * - Geometry::rotation_transform({ double(PI), 0.0, 0.0 }), * Geometry::scale_transform({ cone_radius, cone_radius, cone_height }); -#endif // ENABLE_RAYCAST_PICKING shader->set_uniform("view_model_matrix", view_matrix * model_matrix); const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); @@ -333,11 +265,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glRotated(180., 1., 0., 0.)); glsafe(::glScaled(cone_radius, cone_radius, cone_height)); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_cone.model.render(); -#else - m_cone.render(); -#endif // ENABLE_RAYCAST_PICKING #if !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopMatrix()); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL @@ -353,11 +281,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glPushMatrix()); glsafe(::glScaled(radius, radius, radius)); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_RAYCAST_PICKING m_sphere.model.render(); -#else - m_sphere.render(); -#endif // ENABLE_RAYCAST_PICKING #if !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopMatrix()); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL @@ -371,11 +295,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) } // Now render the drain holes: -#if ENABLE_RAYCAST_PICKING if (has_holes) { -#else - if (has_holes && ! picking) { -#endif // ENABLE_RAYCAST_PICKING render_color = { 0.7f, 0.7f, 0.7f, 0.7f }; #if ENABLE_LEGACY_OPENGL_REMOVAL m_cylinder.set_color(render_color); @@ -544,10 +464,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous m_editing_cache.emplace_back(sla::SupportPoint(pos_and_normal.first, m_new_point_head_diameter/2.f, false), false, pos_and_normal.second); m_parent.set_as_dirty(); m_wait_for_up_event = true; -#if ENABLE_RAYCAST_PICKING on_unregister_raycasters_for_picking(); on_register_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING } else return false; @@ -572,12 +490,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous // Now ask the rectangle which of the points are inside. std::vector points_inside; -#if ENABLE_RAYCAST_PICKING std::vector points_idxs = m_selection_rectangle.contains(points); m_selection_rectangle.stop_dragging(); -#else - std::vector points_idxs = m_selection_rectangle.stop_dragging(m_parent, points); -#endif // ENABLE_RAYCAST_PICKING for (size_t idx : points_idxs) points_inside.push_back(points[idx].cast()); @@ -707,10 +621,8 @@ void GLGizmoSlaSupports::delete_selected_points(bool force) } } -#if ENABLE_RAYCAST_PICKING on_unregister_raycasters_for_picking(); on_register_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING select_point(NoPoints); } @@ -1390,9 +1302,7 @@ void GLGizmoSlaSupports::switch_to_editing_mode() for (const sla::SupportPoint& sp : m_normal_cache) m_editing_cache.emplace_back(sp); select_point(NoPoints); -#if ENABLE_RAYCAST_PICKING on_register_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING m_c->instances_hider()->show_supports(false); m_parent.set_as_dirty(); @@ -1406,9 +1316,7 @@ void GLGizmoSlaSupports::disable_editing_mode() wxGetApp().plater()->leave_gizmos_stack(); m_c->instances_hider()->show_supports(true); m_parent.set_as_dirty(); -#if ENABLE_RAYCAST_PICKING on_unregister_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING } wxGetApp().plater()->get_notification_manager()->close_notification_of_type(NotificationType::QuitSLAManualMode); } @@ -1427,7 +1335,6 @@ bool GLGizmoSlaSupports::unsaved_changes() const return false; } -#if ENABLE_RAYCAST_PICKING void GLGizmoSlaSupports::set_sla_auxiliary_volumes_picking_state(bool state) { std::vector>* raycasters = m_parent.get_raycasters_for_picking(SceneRaycaster::EType::Volume); @@ -1473,7 +1380,6 @@ void GLGizmoSlaSupports::update_raycasters_for_picking_transform() } } } -#endif // ENABLE_RAYCAST_PICKING SlaGizmoHelpDialog::SlaGizmoHelpDialog() : wxDialog(nullptr, wxID_ANY, _L("SLA gizmo keyboard shortcuts"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 136276803e..e8238c8884 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -81,23 +81,13 @@ public: private: bool on_init() override; void on_render() override; -#if ENABLE_RAYCAST_PICKING virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; -#else - void on_render_for_picking() override; -#endif // ENABLE_RAYCAST_PICKING -#if ENABLE_RAYCAST_PICKING void render_points(const Selection& selection); -#else - void render_points(const Selection& selection, bool picking = false); -#endif // ENABLE_RAYCAST_PICKING bool unsaved_changes() const; -#if ENABLE_RAYCAST_PICKING void set_sla_auxiliary_volumes_picking_state(bool state); void update_raycasters_for_picking_transform(); -#endif // ENABLE_RAYCAST_PICKING bool m_lock_unique_islands = false; bool m_editing_mode = false; // Is editing mode active? @@ -110,14 +100,9 @@ private: std::vector m_normal_cache; // to restore after discarding changes or undo/redo ObjectID m_old_mo_id; -#if ENABLE_RAYCAST_PICKING PickingModel m_sphere; PickingModel m_cone; std::vector, std::shared_ptr>> m_raycasters; -#else - GLModel m_cone; - GLModel m_sphere; -#endif // ENABLE_RAYCAST_PICKING GLModel m_cylinder; // This map holds all translated description texts, so they can be easily referenced during layout calculations diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 11c44113bc..b044cc5c85 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -359,11 +359,7 @@ void Raycaster::on_update() if (meshes != m_old_meshes) { m_raycasters.clear(); for (const TriangleMesh* mesh : meshes) -#if ENABLE_RAYCAST_PICKING m_raycasters.emplace_back(new MeshRaycaster(std::make_shared(*mesh))); -#else - m_raycasters.emplace_back(new MeshRaycaster(*mesh)); -#endif // ENABLE_RAYCAST_PICKING m_old_meshes = meshes; } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index c68a510276..9c0f50c8f8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -339,17 +339,6 @@ void GLGizmosManager::render_painter_gizmo() gizmo->render_painter_gizmo(); } -#if !ENABLE_RAYCAST_PICKING -void GLGizmosManager::render_current_gizmo_for_picking_pass() const -{ - if (! m_enabled || m_current == Undefined) - - return; - - m_gizmos[m_current]->render_for_picking(); -} -#endif // !ENABLE_RAYCAST_PICKING - void GLGizmosManager::render_overlay() { if (!m_enabled) @@ -1132,9 +1121,7 @@ bool GLGizmosManager::activate_gizmo(EType type) if (old_gizmo.get_state() != GLGizmoBase::Off) return false; // gizmo refused to be turned off, do nothing. -#if ENABLE_RAYCAST_PICKING old_gizmo.unregister_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING if (!m_serializing && old_gizmo.wants_enter_leave_snapshots()) Plater::TakeSnapshot @@ -1165,9 +1152,7 @@ bool GLGizmosManager::activate_gizmo(EType type) return false; // gizmo refused to be turned on. } -#if ENABLE_RAYCAST_PICKING new_gizmo.register_raycasters_for_picking(); -#endif // ENABLE_RAYCAST_PICKING // sucessful activation of gizmo return true; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 1469c2ef75..b380c55c46 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -216,9 +216,6 @@ public: bool is_hiding_instances() const; void render_current_gizmo() const; -#if !ENABLE_RAYCAST_PICKING - void render_current_gizmo_for_picking_pass() const; -#endif // !ENABLE_RAYCAST_PICKING void render_painter_gizmo(); void render_overlay(); diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 68572c801e..8ac1af7dcd 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -370,13 +370,8 @@ Vec3f MeshRaycaster::get_triangle_normal(size_t facet_idx) const return m_normals[facet_idx]; } -#if ENABLE_RAYCAST_PICKING void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, Vec3d& point, Vec3d& direction) -#else -void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, - Vec3d& point, Vec3d& direction) -#endif // ENABLE_RAYCAST_PICKING { Matrix4d modelview = camera.get_view_matrix().matrix(); Matrix4d projection= camera.get_projection_matrix().matrix(); @@ -540,7 +535,6 @@ std::vector MeshRaycaster::get_unobscured_idxs(const Geometry::Transfo return out; } -#if ENABLE_RAYCAST_PICKING bool MeshRaycaster::closest_hit(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane, size_t* facet_idx) const { @@ -573,7 +567,6 @@ bool MeshRaycaster::closest_hit(const Vec2d& mouse_pos, const Transform3d& trafo return true; } -#endif // ENABLE_RAYCAST_PICKING Vec3f MeshRaycaster::get_closest_point(const Vec3f& point, Vec3f* normal) const { diff --git a/src/slic3r/GUI/MeshUtils.hpp b/src/slic3r/GUI/MeshUtils.hpp index 9db2ed1b1f..f1225c4ff9 100644 --- a/src/slic3r/GUI/MeshUtils.hpp +++ b/src/slic3r/GUI/MeshUtils.hpp @@ -15,9 +15,7 @@ #include #include -#if ENABLE_RAYCAST_PICKING #include -#endif // ENABLE_RAYCAST_PICKING namespace Slic3r { @@ -61,10 +59,8 @@ public: void set_offset(double offset) { m_data[3] = offset; } double get_offset() const { return m_data[3]; } Vec3d get_normal() const { return Vec3d(m_data[0], m_data[1], m_data[2]); } -#if ENABLE_RAYCAST_PICKING void invert_normal() { m_data[0] *= -1.0; m_data[1] *= -1.0; m_data[2] *= -1.0; } ClippingPlane inverted_normal() const { return ClippingPlane(-get_normal(), get_offset()); } -#endif // ENABLE_RAYCAST_PICKING bool is_active() const { return m_data[3] != DBL_MAX; } static ClippingPlane ClipsNothing() { return ClippingPlane(Vec3d(0., 0., 1.), DBL_MAX); } const std::array& get_data() const { return m_data; } @@ -155,7 +151,6 @@ private: // whether certain points are visible or obscured by the mesh etc. class MeshRaycaster { public: -#if ENABLE_RAYCAST_PICKING explicit MeshRaycaster(std::shared_ptr mesh) : m_mesh(mesh) , m_emesh(*mesh, true) // calculate epsilon for triangle-ray intersection from an average edge length @@ -166,20 +161,6 @@ public: static void line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, Vec3d& point, Vec3d& direction); -#else - // The class references extern TriangleMesh, which must stay alive - // during MeshRaycaster existence. - MeshRaycaster(const TriangleMesh& mesh) - : m_emesh(mesh, true) // calculate epsilon for triangle-ray intersection from an average edge length - , m_normals(its_face_normals(mesh.its)) - { - } - - static void line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, - Vec3d& point, Vec3d& direction); -// void line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, -// Vec3d& point, Vec3d& direction) const; -#endif // ENABLE_RAYCAST_PICKING // Given a mouse position, this returns true in case it is on the mesh. bool unproject_on_mesh( @@ -208,7 +189,6 @@ public: const ClippingPlane* clipping_plane = nullptr // clipping plane (if active) ) const; -#if ENABLE_RAYCAST_PICKING // Returns true if the ray, built from mouse position and camera direction, intersects the mesh. // In this case, position and normal contain the position and normal, in model coordinates, of the intersection closest to the camera, // depending on the position/orientation of the clipping_plane, if specified @@ -221,7 +201,6 @@ public: const ClippingPlane* clipping_plane = nullptr, // clipping plane (if active) size_t* facet_idx = nullptr // index of the facet hit ) const; -#endif // ENABLE_RAYCAST_PICKING // Given a point in world coords, the method returns closest point on the mesh. // The output is in mesh coords. @@ -234,14 +213,11 @@ public: Vec3f get_triangle_normal(size_t facet_idx) const; private: -#if ENABLE_RAYCAST_PICKING std::shared_ptr m_mesh; -#endif // ENABLE_RAYCAST_PICKING AABBMesh m_emesh; std::vector m_normals; }; -#if ENABLE_RAYCAST_PICKING struct PickingModel { GLModel model; @@ -252,7 +228,6 @@ struct PickingModel mesh_raycaster.reset(); } }; -#endif // ENABLE_RAYCAST_PICKING } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/SceneRaycaster.cpp b/src/slic3r/GUI/SceneRaycaster.cpp index a92c622c1b..619e26042b 100644 --- a/src/slic3r/GUI/SceneRaycaster.cpp +++ b/src/slic3r/GUI/SceneRaycaster.cpp @@ -4,8 +4,6 @@ #include "Camera.hpp" #include "GUI_App.hpp" -#if ENABLE_RAYCAST_PICKING - namespace Slic3r { namespace GUI { @@ -233,5 +231,3 @@ int SceneRaycaster::decode_id(EType type, int id) { return id - base_id(type); } } // namespace GUI } // namespace Slic3r - -#endif // ENABLE_RAYCAST_PICKING diff --git a/src/slic3r/GUI/SceneRaycaster.hpp b/src/slic3r/GUI/SceneRaycaster.hpp index 2254a2022d..3119e6d1e7 100644 --- a/src/slic3r/GUI/SceneRaycaster.hpp +++ b/src/slic3r/GUI/SceneRaycaster.hpp @@ -1,8 +1,6 @@ #ifndef slic3r_SceneRaycaster_hpp_ #define slic3r_SceneRaycaster_hpp_ -#if ENABLE_RAYCAST_PICKING - #include "MeshUtils.hpp" #include "GLModel.hpp" #include @@ -115,6 +113,4 @@ private: } // namespace GUI } // namespace Slic3r -#endif // ENABLE_RAYCAST_PICKING - #endif // slic3r_SceneRaycaster_hpp_ diff --git a/src/slic3r/Utils/RaycastManager.cpp b/src/slic3r/Utils/RaycastManager.cpp index 14c76722d9..084cf83a63 100644 --- a/src/slic3r/Utils/RaycastManager.cpp +++ b/src/slic3r/Utils/RaycastManager.cpp @@ -26,11 +26,7 @@ void RaycastManager::actualize(const ModelObject *object, const ISkip *skip) }); if (item == m_raycasters.end()) { // add new raycaster -#if ENABLE_RAYCAST_PICKING auto raycaster = std::make_unique(volume->get_mesh_shared_ptr()); -#else // !ENABLE_RAYCAST_PICKING - auto raycaster = std::make_unique(volume->mesh()); -#endif // ENABLE_RAYCAST_PICKING m_raycasters.emplace_back(std::make_pair(oid, std::move(raycaster))); } else { size_t index = item - m_raycasters.begin(); diff --git a/tests/libslic3r/test_color.cpp b/tests/libslic3r/test_color.cpp index 632691669e..bb35f5e38e 100644 --- a/tests/libslic3r/test_color.cpp +++ b/tests/libslic3r/test_color.cpp @@ -20,20 +20,4 @@ SCENARIO("Color encoding/decoding cycle", "[Color]") { } } -#if !ENABLE_RAYCAST_PICKING -SCENARIO("Color picking encoding/decoding cycle", "[Color]") { - GIVEN("Picking color") { - const ColorRGB src_rgb(static_cast(255), static_cast(127), static_cast(63)); - WHEN("apply encode/decode cycle") { - const unsigned int encoded = picking_encode(src_rgb.r_uchar(), src_rgb.g_uchar(), src_rgb.b_uchar()); - const ColorRGBA res_rgba = picking_decode(encoded); - const bool ret = res_rgba.r_uchar() == src_rgb.r_uchar() && res_rgba.g_uchar() == src_rgb.g_uchar() && res_rgba.b_uchar() == src_rgb.b_uchar(); - THEN("result matches source") { - REQUIRE(ret); - } - } - } -} -#endif // !ENABLE_RAYCAST_PICKING -