NEW: add bottom setting for height range function
Change-Id: I0a818dde1e44e9f4475222038916c5ef992461de
This commit is contained in:
parent
ee478072c8
commit
4a143ed8b1
|
@ -0,0 +1,3 @@
|
|||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.0882 3.21873C15.3736 3.51248 15.3736 3.98748 15.0882 4.2781L7.07395 12.5312C6.78859 12.825 6.32717 12.825 6.04484 12.5312L1.91324 8.28123C1.62788 7.98748 1.62788 7.51248 1.91324 7.22185C2.19859 6.93123 2.66002 6.9281 2.94234 7.22185L6.55484 10.9406L14.0561 3.21873C14.3415 2.92498 14.8029 2.92498 15.0852 3.21873H15.0882Z" fill="#00AE42"/>
|
||||
</svg>
|
After Width: | Height: | Size: 456 B |
|
@ -0,0 +1,3 @@
|
|||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.0882 3.21873C15.3736 3.51248 15.3736 3.98748 15.0882 4.2781L7.07395 12.5312C6.78859 12.825 6.32717 12.825 6.04484 12.5312L1.91324 8.28123C1.62788 7.98748 1.62788 7.51248 1.91324 7.22185C2.19859 6.93123 2.66002 6.9281 2.94234 7.22185L6.55484 10.9406L14.0561 3.21873C14.3415 2.92498 14.8029 2.92498 15.0852 3.21873H15.0882Z" fill="#00AE42"/>
|
||||
</svg>
|
After Width: | Height: | Size: 456 B |
|
@ -171,6 +171,7 @@ namespace ImGui
|
|||
const wchar_t UnfoldButtonIcon = 0x0815;
|
||||
const wchar_t SphereButtonIcon = 0x0816;
|
||||
const wchar_t GapFillIcon = 0x0817;
|
||||
const wchar_t ConfirmIcon = 0x0818;
|
||||
|
||||
const wchar_t MinimalizeDarkButton = 0x081C;
|
||||
const wchar_t MinimalizeHoverDarkButton = 0x081D;
|
||||
|
@ -185,6 +186,7 @@ namespace ImGui
|
|||
const wchar_t HeightRangeDarkIcon = 0x0825;
|
||||
const wchar_t SphereButtonDarkIcon = 0x0826;
|
||||
const wchar_t GapFillDarkIcon = 0x0827;
|
||||
const wchar_t ConfirmDarkIcon = 0x0828;
|
||||
|
||||
const wchar_t TextSearchIcon = 0x0828;
|
||||
const wchar_t TextSearchCloseIcon = 0x0829;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
|
@ -140,10 +141,18 @@ void GLGizmoPainterBase::render_cursor() const
|
|||
}
|
||||
}
|
||||
}
|
||||
// Raycast and return if there's no hit.
|
||||
update_raycast_cache(m_parent.get_local_mouse_position(), camera, trafo_matrices);
|
||||
if (m_rr.mesh_id == -1)
|
||||
|
||||
if (m_is_cursor_in_imgui == false) {
|
||||
// Raycast and return if there's no hit.
|
||||
update_raycast_cache(m_parent.get_local_mouse_position(), camera, trafo_matrices);
|
||||
}
|
||||
else {
|
||||
m_rr.mouse_position = m_parent.get_local_mouse_position();
|
||||
}
|
||||
if (m_rr.mesh_id == -1) {
|
||||
m_is_cursor_in_imgui = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_tool_type == ToolType::BRUSH) {
|
||||
if (m_cursor_type == TriangleSelector::SPHERE)
|
||||
|
@ -238,6 +247,21 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
|
|||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
Vec2i GLGizmoPainterBase::_3d_to_mouse(Vec3d pos_in_3d, const Camera &camera) const
|
||||
{
|
||||
Matrix4d modelview = camera.get_view_matrix().matrix();
|
||||
Matrix4d projection = camera.get_projection_matrix().matrix();
|
||||
Vec4i viewport(camera.get_viewport().data());
|
||||
auto screen_width = viewport(2);
|
||||
auto screen_height = viewport(3);
|
||||
Vec4d origin_ndc = projection * modelview * Vec4d(pos_in_3d[0], pos_in_3d[1], pos_in_3d[2], 1.0);
|
||||
Vec4d standard_ndc = origin_ndc / origin_ndc.w();
|
||||
Vec2i screen;
|
||||
screen[0] = screen_width * (standard_ndc[0] + 1.0) / 2.0;
|
||||
screen[1] = screen_height - screen_height * (standard_ndc[1] + 1.0) / 2.0;
|
||||
return screen;
|
||||
}
|
||||
|
||||
// BBS
|
||||
void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) const
|
||||
{
|
||||
|
@ -246,8 +270,69 @@ void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) co
|
|||
float max_z = (float)box.max.z();
|
||||
float min_z = (float)box.min.z();
|
||||
|
||||
float cursor_z = std::clamp((float)hit_world.z(), min_z, max_z);
|
||||
std::array<float, 2> zs = { cursor_z, std::clamp(cursor_z + m_cursor_height, min_z, max_z) };
|
||||
if (m_is_cursor_in_imgui == false) {
|
||||
m_cursor_z = std::clamp((float) hit_world.z(), min_z, max_z);
|
||||
m_height_start_z_in_imgui = m_cursor_z;
|
||||
}
|
||||
ImGuiWrapper &imgui = *wxGetApp().imgui();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 1.0);
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, m_is_dark_mode ? ImVec4(38 / 255.0, 46 / 255.0, 48 / 255.0, 0.7) : ImVec4(255 / 255.0, 255 / 255.0, 255 / 255.0, 0.7));
|
||||
ImGui::SetNextWindowFocus();
|
||||
imgui.set_next_window_pos(m_height_start_pos[0], m_height_start_pos[1], ImGuiCond_Always, 0.0f, 0.0f);
|
||||
|
||||
imgui.begin(wxString("cursor_height_range"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration);
|
||||
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_is_dark_mode ? ImVec4(255 / 255.0, 255 / 255.0, 255 / 255.0, 0.7) : ImVec4(38 / 255.0, 46 / 255.0, 48 / 255.0, 0.7));
|
||||
ImGui::TextUnformatted(_L("Bottom:").ToUTF8().data());
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(50);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, m_is_dark_mode ? ImVec4(38 / 255.0, 46 / 255.0, 48 / 255.0, 0.7) : ImVec4(255 / 255.0, 255 / 255.0, 255 / 255.0, 0.7));
|
||||
ImGui::BBLInputDouble("##m_height_start_z_in_imgui", &m_height_start_z_in_imgui, 0.0f, 0.0f, "%.2f");
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor(1);//for ImGuiCol_FrameBg
|
||||
ImGui::PopStyleColor(1);//for Text
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, m_is_dark_mode ? ImVec4(38 / 255.0, 46 / 255.0, 48 / 255.0, 0.7) : ImVec4(255 / 255.0, 255 / 255.0, 255 / 255.0, 0.7));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, m_is_dark_mode ? ImVec4(50 / 255.0f, 58 / 255.0f, 61 / 255.0f, 1.00f) : ImVec4(238 / 255.0, 238 / 255.0, 238 / 255.0, 1.00f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, m_is_dark_mode ? ImVec4(107 / 255.0f, 107 / 255.0f, 107 / 255.0f, 1.00f) : ImVec4(206 / 255.0f, 206 / 255.0f, 206 / 255.0f, 1.00f));
|
||||
bool btn_clicked = ImGui::Button(into_u8(m_is_dark_mode ? ImGui::ConfirmDarkIcon : ImGui::ConfirmIcon).c_str());
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
auto imgui_size = ImGui::GetWindowSize();
|
||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||
auto screen_height = Vec4i(camera.get_viewport().data())(3);
|
||||
if (m_rr.mouse_position[0] >= m_height_start_pos[0] && m_rr.mouse_position[0] <= m_height_start_pos[0] + imgui_size[0]
|
||||
&& m_rr.mouse_position[1] >= m_height_start_pos[1] && m_rr.mouse_position[1] <= m_height_start_pos[1] + imgui_size[1]) {
|
||||
m_is_cursor_in_imgui = true;
|
||||
m_cursor_z = m_height_start_z_in_imgui;
|
||||
} else {
|
||||
m_is_cursor_in_imgui = false;
|
||||
ImGui::SetNextWindowFocus();
|
||||
}
|
||||
if (btn_clicked) {
|
||||
if (m_cursor_z >= min_z && m_cursor_z + m_cursor_height <= max_z) {
|
||||
m_is_set_height_start_z_by_imgui = true;
|
||||
const_cast<GLGizmoPainterBase &>(*this).gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(0, 0), false, false, false);
|
||||
m_is_set_height_start_z_by_imgui = false;
|
||||
}
|
||||
m_rr.mesh_id = -1; // exit
|
||||
}
|
||||
imgui.set_requires_extra_frame();
|
||||
imgui.end();
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
if (m_cursor_z <= min_z || m_cursor_z + m_cursor_height >= max_z) {
|
||||
return;
|
||||
}
|
||||
std::array<float, 2> zs = {m_cursor_z, std::clamp(m_cursor_z + m_cursor_height, min_z, max_z)};
|
||||
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const ModelObject* model_object = wxGetApp().model().objects[selection.get_object_idx()];
|
||||
|
@ -264,7 +349,7 @@ void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) co
|
|||
}
|
||||
|
||||
for (int i = 0; i < zs.size(); i++) {
|
||||
update_contours(vol_mesh, zs[i], max_z, min_z);
|
||||
update_contours(vol_mesh, zs[i], max_z, min_z, m_is_cursor_in_imgui? false:(i == 0 ? true : false));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z()));
|
||||
|
@ -289,7 +374,12 @@ BoundingBoxf3 GLGizmoPainterBase::bounding_box() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
void GLGizmoPainterBase::update_contours(const TriangleMesh& vol_mesh, float cursor_z, float max_z, float min_z) const
|
||||
struct ScreenPosSort {
|
||||
Vec2i pos_screen;
|
||||
Vec3d pos_3d;
|
||||
};
|
||||
|
||||
void GLGizmoPainterBase::update_contours(const TriangleMesh& vol_mesh, float cursor_z, float max_z, float min_z, bool update_height_start_pos) const
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const GLVolume* first_glvolume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
|
@ -314,6 +404,36 @@ void GLGizmoPainterBase::update_contours(const TriangleMesh& vol_mesh, float cur
|
|||
slicing_params.trafo = Transform3d::Identity().matrix();
|
||||
const Polygons polys = slice_mesh(m_cut_contours.mesh.its, cursor_z, slicing_params);
|
||||
if (!polys.empty()) {
|
||||
if (update_height_start_pos) {
|
||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||
std::vector<ScreenPosSort> screen_pos_sorts;
|
||||
for (size_t i = 0; i < polys.size(); i++) {
|
||||
for (size_t j = 0; j < polys[i].points.size(); j++) {
|
||||
Vec2d pt = unscale(polys[i].points[j]).cast<double>();
|
||||
Vec3d pos_3d(pt[0], pt[1], cursor_z);
|
||||
Vec2i cur_screen_pos = _3d_to_mouse(pos_3d, camera);
|
||||
if (cur_screen_pos[0] >= m_rr.mouse_position[0]) {
|
||||
ScreenPosSort cur{cur_screen_pos, pos_3d};
|
||||
screen_pos_sorts.emplace_back(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(screen_pos_sorts.begin(), screen_pos_sorts.end(), [=](const ScreenPosSort &s1, const ScreenPosSort &s2) {
|
||||
int threshold_x = 20;
|
||||
int threshold_y = 20;
|
||||
if (abs(s1.pos_screen.x() - s2.pos_screen.x()) < threshold_x && abs(s1.pos_screen.y() - s2.pos_screen.y()) > threshold_y) {
|
||||
return abs(s1.pos_screen.y() - m_rr.mouse_position[1]) < abs(s2.pos_screen.y() - m_rr.mouse_position[1]);
|
||||
} else {
|
||||
return s1.pos_screen.x() > s2.pos_screen.x();
|
||||
}
|
||||
});
|
||||
if(screen_pos_sorts.size() >= 1){
|
||||
m_height_start_pos = screen_pos_sorts[0].pos_screen;
|
||||
// make mouse to cover in a part of imgui
|
||||
m_height_start_pos[0] -= 10;
|
||||
m_height_start_pos[1] -= 10;
|
||||
}
|
||||
}
|
||||
m_cut_contours.contours.init_from(polys, static_cast<float>(cursor_z));
|
||||
m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
}
|
||||
|
@ -466,18 +586,19 @@ std::vector<GLGizmoPainterBase::ProjectedHeightRange> GLGizmoPainterBase::get_pr
|
|||
const std::vector<Transform3d>& trafo_matrices) const
|
||||
{
|
||||
std::vector<GLGizmoPainterBase::ProjectedHeightRange> hit_triangles_by_mesh;
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
|
||||
// In mesh_hit_points only the last item could have mesh_id == -1, any other items mustn't.
|
||||
update_raycast_cache(mouse_position, camera, trafo_matrices);
|
||||
if (m_rr.mesh_id == -1)
|
||||
return hit_triangles_by_mesh;
|
||||
|
||||
ProjectedMousePosition mesh_hit_point = { m_rr.hit, m_rr.mesh_id, m_rr.facet };
|
||||
float z_bot_world= (trafo_matrices[m_rr.mesh_id] * Vec3d(m_rr.hit(0), m_rr.hit(1), m_rr.hit(2))).z();
|
||||
float z_top_world = z_bot_world+ m_cursor_height;
|
||||
hit_triangles_by_mesh.push_back({ z_bot_world, m_rr.mesh_id, size_t(m_rr.facet) });
|
||||
float z_bot_world;
|
||||
if (m_is_set_height_start_z_by_imgui == false) {
|
||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||
// In mesh_hit_points only the last item could have mesh_id == -1, any other items mustn't.
|
||||
update_raycast_cache(mouse_position, camera, trafo_matrices);
|
||||
if (m_rr.mesh_id == -1) return hit_triangles_by_mesh;
|
||||
ProjectedMousePosition mesh_hit_point = {m_rr.hit, m_rr.mesh_id, m_rr.facet};
|
||||
z_bot_world = (trafo_matrices[m_rr.mesh_id] * Vec3d(m_rr.hit(0), m_rr.hit(1), m_rr.hit(2))).z();
|
||||
} else {
|
||||
z_bot_world = m_height_start_z_in_imgui;
|
||||
}
|
||||
float z_top_world = z_bot_world + m_cursor_height;
|
||||
hit_triangles_by_mesh.push_back({z_bot_world, m_rr.mesh_id, size_t(m_rr.facet)});
|
||||
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||
|
|
|
@ -366,10 +366,14 @@ private:
|
|||
int instance_idx{ -1 };
|
||||
};
|
||||
mutable CutContours m_cut_contours;
|
||||
|
||||
mutable float m_cursor_z{0};
|
||||
mutable double m_height_start_z_in_imgui{0};
|
||||
mutable bool m_is_set_height_start_z_by_imgui{false};
|
||||
mutable Vec2i m_height_start_pos{0, 0};
|
||||
mutable bool m_is_cursor_in_imgui{false};
|
||||
BoundingBoxf3 bounding_box() const;
|
||||
void update_contours(const TriangleMesh& vol_mesh, float cursor_z, float max_z, float min_z) const;
|
||||
|
||||
void update_contours(const TriangleMesh &vol_mesh, float cursor_z, float max_z, float min_z, bool update_height_start_pos) const;
|
||||
Vec2i _3d_to_mouse(Vec3d pos_in_3d, const Camera &camera) const;
|
||||
protected:
|
||||
void on_set_state() override;
|
||||
void on_start_dragging() override {}
|
||||
|
|
|
@ -63,6 +63,7 @@ static const std::map<const wchar_t, std::string> font_icons = {
|
|||
{ImGui::TriangleButtonIcon , "triangle_paint" },
|
||||
{ImGui::FillButtonIcon , "fill_paint" },
|
||||
{ImGui::HeightRangeIcon , "height_range" },
|
||||
{ImGui::ConfirmIcon , "confirm" },
|
||||
{ImGui::GapFillIcon , "gap_fill" },
|
||||
{ImGui::FoldButtonIcon , "im_fold" },
|
||||
{ImGui::UnfoldButtonIcon , "im_unfold" },
|
||||
|
@ -79,6 +80,7 @@ static const std::map<const wchar_t, std::string> font_icons = {
|
|||
{ImGui::TriangleButtonDarkIcon , "triangle_paint_dark" },
|
||||
{ImGui::FillButtonDarkIcon , "fill_paint_dark" },
|
||||
{ImGui::HeightRangeDarkIcon , "height_range_dark" },
|
||||
{ImGui::ConfirmDarkIcon , "confirm_dark" },
|
||||
{ImGui::GapFillDarkIcon , "gap_fill_dark" },
|
||||
{ImGui::SphereButtonDarkIcon , "toolbar_modifier_sphere_dark" },
|
||||
|
||||
|
|
Loading…
Reference in New Issue