From b5db8bc4c3d44c387cf0d42197964811d538d88b Mon Sep 17 00:00:00 2001 From: "zhou.xu" Date: Tue, 12 Mar 2024 20:05:09 +0800 Subject: [PATCH] NEW:modify distance between meshs Jira: STUDIO-6166 Change-Id: I41ccfebf3b21b9bb21fa0f1f018d5e3146b86e5e --- src/libslic3r/Measure.cpp | 80 +++++--- src/libslic3r/Measure.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 251 ++++++++++++----------- src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp | 3 + src/slic3r/GUI/ImGuiWrapper.cpp | 3 + src/slic3r/GUI/ImGuiWrapper.hpp | 3 + src/slic3r/GUI/Selection.cpp | 12 ++ src/slic3r/GUI/Selection.hpp | 1 + 8 files changed, 211 insertions(+), 144 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 7494a937e..2bb775b64 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -807,7 +807,7 @@ static AngleAndEdges angle_plane_plane(const std::tuple& p1, return ret; } -MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& b) +MeasurementResult get_measurement(const SurfaceFeature &a, const SurfaceFeature &b, bool deal_circle_result) { assert(a.get_type() != SurfaceFeatureType::Undef && b.get_type() != SurfaceFeatureType::Undef); @@ -824,7 +824,7 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& if (f2.get_type() == SurfaceFeatureType::Point) { Vec3d diff = (f2.get_point() - f1.get_point()); result.distance_strict = std::make_optional(DistAndPoints{diff.norm(), f1.get_point(), f2.get_point()}); - result.distance_xyz = diff.cwiseAbs(); + result.distance_xyz = diff; /////////////////////////////////////////////////////////////////////////// } else if (f2.get_type() == SurfaceFeatureType::Edge) { @@ -854,13 +854,18 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& result.distance_strict = std::make_optional(DistAndPoints{ radius, c, p_on_circle }); } else { - const Eigen::Hyperplane circle_plane(n, c); - const Vec3d proj = circle_plane.projection(f1.get_point()); - const double dist = std::sqrt(std::pow((proj - c).norm() - radius, 2.) + - (f1.get_point() - proj).squaredNorm()); + if (deal_circle_result == false) { + const Eigen::Hyperplane circle_plane(n, c); + const Vec3d proj = circle_plane.projection(f1.get_point()); + const double dist = std::sqrt(std::pow((proj - c).norm() - radius, 2.) + (f1.get_point() - proj).squaredNorm()); - const Vec3d p_on_circle = c + radius * (proj - c).normalized(); - result.distance_strict = std::make_optional(DistAndPoints{ dist, f1.get_point(), p_on_circle }); // TODO + const Vec3d p_on_circle = c + radius * (proj - c).normalized(); + result.distance_strict = std::make_optional(DistAndPoints{dist, f1.get_point(), p_on_circle}); + } + else { + const double dist = (f1.get_point() - c).norm(); + result.distance_strict = std::make_optional(DistAndPoints{dist, f1.get_point(), c}); + } } /////////////////////////////////////////////////////////////////////////// } else if (f2.get_type() == SurfaceFeatureType::Plane) { @@ -908,27 +913,29 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& result.angle = angle_edge_edge(f1.get_edge(), f2.get_edge()); /////////////////////////////////////////////////////////////////////////// } else if (f2.get_type() == SurfaceFeatureType::Circle) { - const std::pair e = f1.get_edge(); - const auto& [center, radius, normal] = f2.get_circle(); - const Vec3d e1e2 = (e.second - e.first); - const Vec3d e1e2_unit = e1e2.normalized(); + const std::pair e = f1.get_edge(); + const auto &[center, radius, normal] = f2.get_circle(); + const Vec3d e1e2 = (e.second - e.first); + const Vec3d e1e2_unit = e1e2.normalized(); std::vector distances; distances.emplace_back(*get_measurement(SurfaceFeature(e.first), f2).distance_strict); distances.emplace_back(*get_measurement(SurfaceFeature(e.second), f2).distance_strict); - const Eigen::Hyperplane plane(e1e2_unit, center); - const Eigen::ParametrizedLine line = Eigen::ParametrizedLine::Through(e.first, e.second); - const Vec3d inter = line.intersectionPoint(plane); - const Vec3d e1inter = inter - e.first; - if (e1inter.dot(e1e2) >= 0.0 && e1inter.norm() < e1e2.norm()) - distances.emplace_back(*get_measurement(SurfaceFeature(inter), f2).distance_strict); + const Eigen::Hyperplane plane(e1e2_unit, center); + const Eigen::ParametrizedLine line = Eigen::ParametrizedLine::Through(e.first, e.second); + const Vec3d inter = line.intersectionPoint(plane); + const Vec3d e1inter = inter - e.first; + if (e1inter.dot(e1e2) >= 0.0 && e1inter.norm() < e1e2.norm()) distances.emplace_back(*get_measurement(SurfaceFeature(inter), f2).distance_strict); - auto it = std::min_element(distances.begin(), distances.end(), - [](const DistAndPoints& item1, const DistAndPoints& item2) { - return item1.dist < item2.dist; - }); - result.distance_infinite = std::make_optional(DistAndPoints{it->dist, it->from, it->to}); + auto it = std::min_element(distances.begin(), distances.end(), [](const DistAndPoints &item1, const DistAndPoints &item2) { return item1.dist < item2.dist; }); + if (deal_circle_result == false) { + result.distance_infinite = std::make_optional(DistAndPoints{it->dist, it->from, it->to}); + } + else{ + const double dist = (it->from - center).norm(); + result.distance_infinite = std::make_optional(DistAndPoints{dist, it->from, center}); + } /////////////////////////////////////////////////////////////////////////// } else if (f2.get_type() == SurfaceFeatureType::Plane) { const auto [from, to] = f1.get_edge(); @@ -1190,8 +1197,14 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& info.sqrDistance = distance * distance; } - - result.distance_infinite = std::make_optional(DistAndPoints{ std::sqrt(candidates[0].sqrDistance), candidates[0].circle0Closest, candidates[0].circle1Closest }); // TODO + if (deal_circle_result == false) { + result.distance_infinite = std::make_optional( + DistAndPoints{std::sqrt(candidates[0].sqrDistance), candidates[0].circle0Closest, candidates[0].circle1Closest}); // TODO + } else { + const double dist = (c0 - c1).norm(); + result.distance_strict = std::make_optional(DistAndPoints{dist, c0, c1}); + } + /////////////////////////////////////////////////////////////////////////// } else if (f2.get_type() == SurfaceFeatureType::Plane) { const auto [center, radius, normal1] = f1.get_circle(); @@ -1237,13 +1250,26 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& if (are_parallel(normal1, normal2)) { // The planes are parallel, calculate distance. - const Eigen::Hyperplane plane(normal1, pt1); - result.distance_infinite = std::make_optional(DistAndPoints{ plane.absDistance(pt2), pt2, plane.projection(pt2) }); // TODO + const Eigen::Hyperplane plane(normal2, pt2); + result.distance_infinite = std::make_optional(DistAndPoints{ plane.absDistance(pt1), pt1, plane.projection(pt1) }); } else result.angle = angle_plane_plane(f1.get_plane(), f2.get_plane()); } + if (swap) { + auto swap_dist_and_points = [](DistAndPoints& dp) { + auto back = dp.to; + dp.to = dp.from; + dp.from = back; + }; + if (result.distance_infinite.has_value()) { + swap_dist_and_points(*result.distance_infinite); + } + if (result.distance_strict.has_value()) { + swap_dist_and_points(*result.distance_strict); + } + } return result; } diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index da14ab680..2ea402510 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -180,7 +180,7 @@ struct MeasurementResult { }; // Returns distance/angle between two SurfaceFeatures. -MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& b); +MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& b,bool deal_circle_result =false); inline Vec3d edge_direction(const Vec3d& from, const Vec3d& to) { return (to - from).normalized(); } inline Vec3d edge_direction(const std::pair& e) { return edge_direction(e.first, e.second); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 20a1cfb5d..e66bdbfd8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -441,12 +441,18 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event) m_imgui->set_requires_extra_frame(); const Measure::MeasurementResult &measure = m_measurement_result; + m_distance = Vec3d::Zero(); if (measure.distance_xyz.has_value() && measure.distance_xyz->norm() > EPSILON) { - Vec3d distance = *measure.distance_xyz; - if (wxGetApp().app_config->get("use_inches") == "1") - distance = GizmoObjectManipulation::mm_to_in * distance; - m_buffered_distance = distance; + m_distance = *measure.distance_xyz; } + else if (measure.distance_infinite.has_value()) { + m_distance = measure.distance_infinite->to - measure.distance_infinite->from; + } else if (measure.distance_strict.has_value()) { + m_distance = measure.distance_strict->to - measure.distance_strict->from; + } + if (wxGetApp().app_config->get("use_inches") == "1") + m_distance = GizmoObjectManipulation::mm_to_in * m_distance; + m_buffered_distance = m_distance; return true; } else @@ -570,6 +576,7 @@ void GLGizmoMeasure::on_set_state() m_mode = EMode::FeatureSelection; m_hover_id = -1; m_show_reset_first_tip = false; + m_distance = Vec3d::Zero(); } } @@ -700,41 +707,36 @@ void GLGizmoMeasure::on_render() } if (m_mouse_left_down_mesh_deal && m_hover_id >= 0) { m_mouse_left_down_mesh_deal = false; - if (m_selected_features.first.feature.has_value()) { - if (m_hit_order_volumes.size() == 0) { - m_hit_order_volumes.push_back(m_last_hit_volume); - } else { - m_hit_order_volumes[0] = m_last_hit_volume; - } - } if (m_selected_features.second.feature.has_value()) { if (m_hit_order_volumes.size() == 1) { m_hit_order_volumes.push_back(m_last_hit_volume); } else { m_hit_order_volumes[1] = m_last_hit_volume; } + // deal hit_different_volumes + if (m_hit_different_volumes.size() >= 1) { + if (m_last_hit_volume == m_hit_different_volumes[0]) { + //do nothing + } else { + if (m_hit_different_volumes.size() == 2) { + m_hit_different_volumes[1] = m_last_hit_volume; + } else { + m_hit_different_volumes.push_back(m_last_hit_volume); + } + } + } } - - auto is_two_volume_pick = [this, &camera]() { - if (m_mesh_raycaster_map.size() < 2) { - return false; + else if (m_selected_features.first.feature.has_value()) { + if (m_hit_order_volumes.size() == 0) { + m_hit_order_volumes.push_back(m_last_hit_volume); + } else { + m_hit_order_volumes[0] = m_last_hit_volume; } - auto hit_volume = m_last_hit_volume; - if (hit_volume) { - if (m_hit_different_volumes.size() == 0) { - m_hit_different_volumes.push_back(hit_volume); - return true; - } - if (m_hit_different_volumes.size() == 1 && hit_volume == m_hit_different_volumes[0]) { - return false; - } - m_hit_different_volumes.push_back(hit_volume); - return true; + //deal hit_different_volumes + if (m_hit_different_volumes.size() == 0) { + m_hit_different_volumes.push_back(m_last_hit_volume); } - return false; - }; - - is_two_volume_pick(); + } } } //const bool mouse_on_object = m_raycaster->unproject_on_mesh(mouse_position, Transform3d::Identity(), camera, position_on_model, normal_on_model, nullptr, &model_facet_idx); @@ -1197,8 +1199,8 @@ void GLGizmoMeasure::render_dimensioning() if (shader == nullptr) return; - auto point_point = [this, &shader](const Vec3d& v1, const Vec3d& v2, float distance) { - if ((v2 - v1).squaredNorm() < 0.000001 || distance < 0.001f) + auto point_point = [this, &shader](const Vec3d &v1, const Vec3d &v2, float distance, const std::array &color, bool show_label = true, bool show_first_tri = true) { + if ((v2 - v1).squaredNorm() < 0.000001 || abs(distance) < 0.001f) return; const Camera& camera = wxGetApp().plater()->get_camera(); @@ -1249,7 +1251,7 @@ void GLGizmoMeasure::render_dimensioning() 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 }) : ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss * Geometry::scale_transform({ v12ss_len, 1.0f, 1.0f })); - m_dimensioning.line.set_color(-1,ColorRGBA::WHITE().get_data()); + m_dimensioning.line.set_color(-1, color); m_dimensioning.line.render(); #if ENABLE_GL_CORE_PROFILE @@ -1267,11 +1269,12 @@ void GLGizmoMeasure::render_dimensioning() glsafe(::glLineWidth(1.0f)); // arrow 1 - shader->set_uniform("view_model_matrix", overlap ? - ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss : - ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q21ss); - m_dimensioning.triangle.render(); - + if (show_first_tri) { + shader->set_uniform("view_model_matrix", overlap ? + ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss : + ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q21ss); + m_dimensioning.triangle.render(); + } // arrow 2 shader->set_uniform("view_model_matrix", overlap ? ss_to_ndc_matrix * Geometry::translation_transform(v2ss_3) * q21ss : @@ -1290,7 +1293,7 @@ void GLGizmoMeasure::render_dimensioning() m_imgui->set_next_window_pos(label_position.x(), viewport[3] - label_position.y(), ImGuiCond_Always, 0.0f, 1.0f); m_imgui->set_next_window_bg_alpha(0.0f); - if (!m_editing_distance) { + if (!m_editing_distance && show_label) { ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 1.0f, 1.0f }); @@ -1333,35 +1336,6 @@ void GLGizmoMeasure::render_dimensioning() const double ratio = new_value / old_value; wxGetApp().plater()->take_snapshot(_u8L("Scale")); - - auto scale_feature = [this](Measure::SurfaceFeature& feature) { - Measure::Measuring *cur_measuring = get_measuring_of_mesh(feature.mesh, feature.world_tran); - switch (feature.get_type()) - { - case Measure::SurfaceFeatureType::Point: - case Measure::SurfaceFeatureType::Edge: - case Measure::SurfaceFeatureType::Circle: - case Measure::SurfaceFeatureType::Plane: - { - feature.clone(*feature.origin_surface_feature); - feature.translate(feature.world_tran); - if (feature.get_type() == Measure::SurfaceFeatureType::Circle) { - m_feature_circle_first.last_circle_feature = nullptr; - m_feature_circle_first.inv_zoom = 0; - m_feature_circle_second.last_circle_feature = nullptr; - m_feature_circle_second.inv_zoom = 0; - } - if (feature.get_type() == Measure::SurfaceFeatureType::Plane) { - if (cur_measuring) { - update_world_plane_features(cur_measuring, feature); - } - } - break; - } - default: { break; } - } - }; - // apply scale TransformationType type; type.set_world(); @@ -1371,21 +1345,18 @@ void GLGizmoMeasure::render_dimensioning() // scale selection Selection& selection = m_parent.get_selection(); selection.setup_cache(); - Vec3d old_center, new_center; if (scale_single_volume && m_hit_different_volumes.size()==1) { - //todo//update_single_mesh_world_tran + //todo//update_single_mesh_pick(m_hit_different_volumes[0]) } else { - old_center = selection.get_bounding_box().center(); selection.scale(ratio * Vec3d::Ones(), type); wxGetApp().plater()->canvas3D()->do_scale(""); // avoid storing another snapshot - new_center = selection.get_bounding_box().center(); register_single_mesh_pick(); } wxGetApp().obj_manipul()->set_dirty(); // scale dimensioning - scale_feature(*m_selected_features.first.feature); + update_feature_by_tran(*m_selected_features.first.feature); if (m_selected_features.second.feature.has_value()) - scale_feature(*m_selected_features.second.feature); + update_feature_by_tran(*m_selected_features.second.feature); // update measure on next call to data_changed() m_pending_scale = true; @@ -1742,7 +1713,17 @@ void GLGizmoMeasure::render_dimensioning() 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); + if (m_selected_features.second.feature.has_value()) { + auto x_to = dap.from; + x_to[0] = dap.to[0]; + point_point(dap.from, x_to, x_to[0] - dap.from[0], ColorRGBA::RED().get_data(), false, false); + auto y_to = x_to; + y_to[1] = dap.to[1]; + point_point(x_to, y_to, y_to[1] - x_to[1], ColorRGBA::GREEN().get_data(), false, false); + point_point(y_to, dap.to, dap.to[2] - y_to[2], ColorRGBA::BLUE().get_data(), false, false); + } + + point_point(dap.from, dap.to, dap.dist, ColorRGBA::WHITE().get_data()); } glsafe(::glEnable(GL_DEPTH_TEST)); @@ -1991,64 +1972,67 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit wxTheClipboard->Close(); } }; - auto add_edit_distance_xyz_box = [this, ¤t_active_id](Vec3d distance) { + auto add_edit_distance_xyz_box = [this, ¤t_active_id](Vec3d& distance) { + float buf_size_max = ImGui::CalcTextSize("-100.00").x * 1.2; ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - m_imgui->text_colored(ImGuiWrapper::COL_BAMBU, "X:"); + m_imgui->text_colored(ImGuiWrapper::COL_RED, "X:"); ImGui::TableSetColumnIndex(1); + ImGui::PushItemWidth(buf_size_max); ImGui::BBLInputDouble("##measure_distance_x", &m_buffered_distance[0], 0.0f, 0.0f, "%.2f"); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - m_imgui->text_colored(ImGuiWrapper::COL_BAMBU, "Y:"); + m_imgui->text_colored(ImGuiWrapper::COL_GREEN, "Y:"); ImGui::TableSetColumnIndex(1); ImGui::BBLInputDouble("##measure_distance_y", &m_buffered_distance[1], 0.0f, 0.0f, "%.2f"); + bool same_model_object = is_two_volume_in_same_model_object(); - m_imgui->disabled_begin(same_model_object); + m_imgui->disabled_begin(!same_model_object); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - m_imgui->text_colored(ImGuiWrapper::COL_BAMBU, "Z:"); + m_imgui->text_colored(ImGuiWrapper::COL_BLUE, "Z:"); ImGui::TableSetColumnIndex(1); ImGui::BBLInputDouble("##measure_distance_z", &m_buffered_distance[2], 0.0f, 0.0f, "%.2f"); + m_imgui->disabled_end(); - ImGui::TableNextRow(); + /*ImGui::TableNextRow(); if (m_imgui->button(_L("Adsorbed onto the surface"))) { - std::cout << ""; - } + std::cout << "todo"; + }*/ m_imgui->disabled_end(); if (m_last_active_item_imgui != current_active_id && m_hit_different_volumes.size() == 2) { auto selection = const_cast(&m_parent.get_selection()); + selection->setup_cache(); Vec3d displacement = Vec3d::Zero(); - auto v = m_hit_different_volumes[1]; + auto v = m_hit_different_volumes[1]; if (std::abs(m_buffered_distance[0] - distance[0]) > EPSILON) { - if (same_model_object == false) { - wxGetApp().plater()->take_snapshot(_u8L("modify x distance between objects")); - displacement[0] = m_buffered_distance[0] - distance[0]; - auto world_tran = v->get_instance_transformation() * v->get_volume_transformation(); - selection->translate(v->object_idx(), v->instance_idx(), displacement); - distance[0] = m_buffered_distance[0]; - } + wxGetApp().plater()->take_snapshot("modify x distance between objects"); + displacement[0] = m_buffered_distance[0] - distance[0]; + distance[0] = m_buffered_distance[0]; } else if (std::abs(m_buffered_distance[1] - distance[1]) > EPSILON) { - if (same_model_object == false) { - wxGetApp().plater()->take_snapshot(_u8L("modify y distance between objects")); - displacement[1] = m_buffered_distance[1] - distance[1]; - selection->translate(v->object_idx(), v->instance_idx(), displacement); - distance[1] = m_buffered_distance[1]; - } + wxGetApp().plater()->take_snapshot("modify y distance between objects"); + displacement[1] = m_buffered_distance[1] - distance[1]; + distance[1] = m_buffered_distance[1]; } else if (std::abs(m_buffered_distance[2] - distance[2]) > EPSILON) { - if (same_model_object == false) { - wxGetApp().plater()->take_snapshot(_u8L("modify y distance between objects")); - displacement[2] = m_buffered_distance[2] - distance[2]; - selection->translate(v->object_idx(), v->instance_idx(), displacement); - distance[2] = m_buffered_distance[2]; - } + wxGetApp().plater()->take_snapshot("modify z distance between objects"); + displacement[2] = m_buffered_distance[2] - distance[2]; + distance[2] = m_buffered_distance[2]; + } + if (displacement.norm() > 0.0f) { + wxGetApp().plater()->take_snapshot(_u8L("MoveInMeasure"));// avoid storing another snapshot + selection->set_mode(same_model_object ? Selection::Volume : Selection::Instance); + auto llo = selection->get_mode(); + if (same_model_object == false) { + selection->translate(v->object_idx(), v->instance_idx(), displacement); + } else { + selection->translate(v->object_idx(), v->instance_idx(), v->volume_idx(), displacement); + } + wxGetApp().plater()->canvas3D()->do_move(""); + update_single_mesh_pick(v); + update_feature_by_tran(*m_selected_features.second.feature); + m_pending_scale = true; } - //m_measuring.reset(); - update_if_needed(); - std::future resultFuture = std::async(std::launch::async, [this]() { this->register_single_mesh_pick(); }); - //todo and undo:remember 2 featura to solve - m_selected_features.second.feature->translate(displacement); - update_measurement_result(); } }; ImGui::Separator(); @@ -2101,6 +2085,9 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit ImGui::PopID(); } } + if (m_distance.norm() >0.01 && m_hit_different_volumes.size() == 2) { + add_edit_distance_xyz_box(m_distance); + } } // add dummy rows to keep dialog size fixed /*for (unsigned int i = measure_row_count; i < max_measure_row_count; ++i) { @@ -2144,7 +2131,7 @@ 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_measurement_result = Measure::get_measurement(*m_selected_features.first.feature, *m_selected_features.second.feature,true); 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()))); } @@ -2221,14 +2208,21 @@ void GLGizmoMeasure::register_single_mesh_pick() } } +void GLGizmoMeasure::update_single_mesh_pick(GLVolume *v) +{ + if (m_mesh_raycaster_map.find(v) != m_mesh_raycaster_map.end()) { + auto world_tran = v->get_instance_transformation() * v->get_volume_transformation(); + m_mesh_raycaster_map[v]->world_tran.set_from_transform(world_tran.get_matrix()); + } +} + void GLGizmoMeasure::reset_all_feature() { reset_feature2(); reset_feature1(); m_show_reset_first_tip = false; m_hit_different_volumes.clear(); - m_hit_different_volumes.reserve(2); - m_hit_order_volumes.clear(); m_hit_order_volumes.clear(); + m_last_hit_volume = nullptr; } void GLGizmoMeasure::reset_feature1() @@ -2248,12 +2242,10 @@ void GLGizmoMeasure::reset_feature1() m_selected_features.first.feature.reset(); m_show_reset_first_tip = false; if (m_hit_different_volumes.size() == 1) { - m_hit_different_volumes[0] = m_hit_different_volumes[1]; - m_hit_different_volumes.erase(m_hit_different_volumes.begin() + 0); + m_hit_different_volumes.clear(); } if (m_hit_order_volumes.size() == 1) { - m_hit_order_volumes[0] = m_hit_order_volumes[1]; - m_hit_order_volumes.erase(m_hit_order_volumes.begin() + 0); + m_hit_order_volumes.clear(); } if (m_feature_plane_first.plane) { m_feature_plane_first.plane->reset(); @@ -2340,5 +2332,32 @@ void GLGizmoMeasure::update_world_plane_features(Measure::Measuring *cur_measuri } } +void GLGizmoMeasure::update_feature_by_tran(Measure::SurfaceFeature &feature) +{ + Measure::Measuring *cur_measuring = get_measuring_of_mesh(feature.mesh, feature.world_tran); + switch (feature.get_type()) { + case Measure::SurfaceFeatureType::Point: + case Measure::SurfaceFeatureType::Edge: + case Measure::SurfaceFeatureType::Circle: + case Measure::SurfaceFeatureType::Plane: { + feature.clone(*feature.origin_surface_feature); + feature.translate(feature.world_tran); + if (feature.get_type() == Measure::SurfaceFeatureType::Circle) { + m_feature_circle_first.last_circle_feature = nullptr; + m_feature_circle_first.inv_zoom = 0; + m_feature_circle_second.last_circle_feature = nullptr; + m_feature_circle_second.inv_zoom = 0; + } + if (feature.get_type() == Measure::SurfaceFeatureType::Plane) { + if (cur_measuring) { update_world_plane_features(cur_measuring, feature); } + } + break; + } + default: { + break; + } + } +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp index 14d715384..efb520c0c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.hpp @@ -126,6 +126,7 @@ class GLGizmoMeasure : public GLGizmoBase //std::vector> m_plane_models_cache; unsigned int m_last_active_item_imgui{0}; Vec3d m_buffered_distance; + Vec3d m_distance; // used to keep the raycasters for point/center spheres //std::vector> m_selected_sphere_raycasters; std::optional m_curr_feature; @@ -192,6 +193,7 @@ protected: void reset_all_pick(); void reset_gripper_pick(GripperType id,bool is_all = false); void register_single_mesh_pick(); + void update_single_mesh_pick(GLVolume* v); void reset_all_feature(); void reset_feature1(); @@ -199,6 +201,7 @@ protected: bool is_two_volume_in_same_model_object(); Measure::Measuring* get_measuring_of_mesh(indexed_triangle_set *mesh, Transform3d &tran); void update_world_plane_features(Measure::Measuring *cur_measuring, Measure::SurfaceFeature &feautre); + void update_feature_by_tran(Measure::SurfaceFeature & feature); private: // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 2e892d654..788a37fd9 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -150,6 +150,9 @@ const ImVec4 ImGuiWrapper::COL_BUTTON_HOVERED = COL_ORANGE_LIGHT; const ImVec4 ImGuiWrapper::COL_BUTTON_ACTIVE = ImGuiWrapper::COL_BUTTON_HOVERED; //BBS +const ImVec4 ImGuiWrapper::COL_RED = ImVec4(1.0f, 0.0f, 0.0f, 1.0f); +const ImVec4 ImGuiWrapper::COL_GREEN = ImVec4(0.0f, 1.0f, 0.0f, 1.0f); +const ImVec4 ImGuiWrapper::COL_BLUE = ImVec4(0.0f, 0.0f, 1.0f, 1.0f); const ImVec4 ImGuiWrapper::COL_BLUE_LIGHT = ImVec4(0.122f, 0.557f, 0.918f, 1.0f); const ImVec4 ImGuiWrapper::COL_GREEN_LIGHT = ImVec4(0.86f, 0.99f, 0.91f, 1.0f); const ImVec4 ImGuiWrapper::COL_HOVER = { 0.933f, 0.933f, 0.933f, 1.0f }; diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 1d6c7917f..f87729224 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -209,6 +209,9 @@ public: static const ImVec4 COL_BUTTON_ACTIVE; //BBS add more colors + static const ImVec4 COL_RED; + static const ImVec4 COL_GREEN; + static const ImVec4 COL_BLUE; static const ImVec4 COL_BLUE_LIGHT; static const ImVec4 COL_GREEN_LIGHT; static const ImVec4 COL_HOVER; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index f66affeff..454d5390c 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1552,6 +1552,18 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co this->set_bounding_boxes_dirty(); } +void Selection::translate(unsigned int object_idx, unsigned int instance_idx, unsigned int volume_idx, const Vec3d &displacement) { + if (!m_valid) return; + + for (unsigned int i : m_list) { + GLVolume &v = *(*m_volumes)[i]; + if (v.object_idx() == (int) object_idx && v.instance_idx() == (int) instance_idx && v.volume_idx() == (int) volume_idx) + v.set_volume_offset(v.get_volume_offset() + displacement); + } + + this->set_bounding_boxes_dirty(); +} + //BBS: add partplate related logic void Selection::notify_instance_update(int object_idx, int instance_idx) { diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index e4d962e28..2f58920c2 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -366,6 +366,7 @@ public: void translate(unsigned int object_idx, const Vec3d& displacement); void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement); + void translate(unsigned int object_idx, unsigned int instance_idx, unsigned int volume_idx, const Vec3d &displacement); //BBS: add partplate related logic void notify_instance_update(int object_idx, int instance_idx); // BBS