diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 91fdcf3b4b..6b2968bb0e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -187,6 +187,7 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, , m_connector_shape_id (int(CutConnectorShape::Circle)) { m_connector_type = CutConnectorType::Snap; + m_mode = size_t(CutMode::cutTongueAndGroove); m_modes = { _u8L("Planar"), _u8L("Tongue and Groove")//, _u8L("Grid") // , _u8L("Radial"), _u8L("Modular") @@ -487,6 +488,10 @@ bool GLGizmoCut3D::render_cut_mode_combo() m_contour_width = CutMode(m_mode) == CutMode::cutTongueAndGroove ? 0.f : 0.4f; oc->set_behavior(m_connectors_editing, m_connectors_editing, double(m_contour_width)); } + if (m_use_TAG_mesh) { + m_plane.reset(); + on_unregister_raycasters_for_picking(); + } reset_cut_by_contours(); } @@ -861,6 +866,263 @@ indexed_triangle_set GLGizmoCut3D::its_make_sides_groove_plane(float flaps_width }; } + + +indexed_triangle_set GLGizmoCut3D::its_make_groove_plane() +{ + // values for calculation + + const float side_width = is_approx(m_groove_flaps_angle, 0.f) ? m_groove_depth : (m_groove_depth / sin(m_groove_flaps_angle)); + const float flaps_width = 2.f * side_width * cos(m_groove_flaps_angle); + + const float groove_half_width_upper = 0.5f * (m_groove_width); + const float groove_half_width_lower = 0.5f * (m_groove_width + flaps_width); + + const float cut_plane_radius = 1.5f * float(m_radius); + const float cut_plane_length = 1.5f * cut_plane_radius; + + const float groove_half_depth = 0.5f * m_groove_depth; + + const float x = 0.5f * cut_plane_radius; + const float y = 0.5f * cut_plane_length; + float z_upper = groove_half_depth; + float z_lower = -groove_half_depth; + + const float proj = y * tan(m_groove_angle); + + float ext_upper_x = groove_half_width_upper + proj; // upper_x extension + float ext_lower_x = groove_half_width_lower + proj; // lower_x extension + + float nar_upper_x = groove_half_width_upper - proj; // upper_x narrowing + float nar_lower_x = groove_half_width_lower - proj; // lower_x narrowing + + const float cut_plane_thiknes = 0.02f;// 0.02f * (float)get_grabber_mean_size(m_bounding_box); // cut_plane_thiknes + + + // Different cases of groove plane: + + // groove is open + + if (groove_half_width_upper > proj && groove_half_width_lower > proj) { + indexed_triangle_set mesh; + + auto get_vertices = [x, y](float z_upper, float z_lower, float nar_upper_x, float nar_lower_x, float ext_upper_x, float ext_lower_x) { + return std::vector({ + // upper left part vertices + {-x, -y, z_upper}, {-x, y, z_upper}, {-nar_upper_x, y, z_upper}, {-ext_upper_x, -y, z_upper}, + // lower part vertices + {-ext_lower_x, -y, z_lower}, {-nar_lower_x, y, z_lower}, {nar_lower_x, y, z_lower}, {ext_lower_x, -y, z_lower}, + // upper right part vertices + {ext_upper_x, -y, z_upper}, {nar_upper_x, y, z_upper}, {x, y, z_upper}, {x, -y, z_upper} + }); + }; + + mesh.vertices = get_vertices(z_upper, z_lower, nar_upper_x, nar_lower_x, ext_upper_x, ext_lower_x); + mesh.vertices.reserve(2 * mesh.vertices.size()); + + z_upper -= cut_plane_thiknes; + z_lower -= cut_plane_thiknes; + if (m_use_TAG_mesh_full) { + const float under_x_shift = cut_plane_thiknes / tan(0.5f * m_groove_flaps_angle); + + nar_upper_x += under_x_shift; + nar_lower_x += under_x_shift; + ext_upper_x += under_x_shift; + ext_lower_x += under_x_shift; + + std::vector vertices = get_vertices(z_upper, z_lower, nar_upper_x, nar_lower_x, ext_upper_x, ext_lower_x); + mesh.vertices.insert(mesh.vertices.end(), vertices.begin(), vertices.end()); + + mesh.indices = { + // above view + {5,4,7}, {5,7,6}, // lower part + {3,4,5}, {3,5,2}, // left side + {9,6,8}, {8,6,7}, // right side + {1,0,2}, {2,0,3}, // upper left part + {9,8,10}, {10,8,11}, // upper right part + // under view + {20,21,22}, {20,22,23}, // upper right part + {12,13,14}, {12,14,15}, // upper left part + {18,21,20}, {18,20,19}, // right side + {16,15,14}, {16,14,17}, // left side + {16,17,18}, {16,18,19}, // lower part + // left edge + {1,13,0}, {0,13,12}, + // front edge + {0,12,3}, {3,12,15}, {3,15,4}, {4,15,16}, {4,16,7}, {7,16,19}, {7,19,20}, {7,20,8}, {8,20,11}, {11,20,23}, + // right edge + {11,23,10}, {10,23,22}, + // back edge + {1,13,2}, {2,13,14}, {2,14,17}, {2,17,5}, {5,17,6}, {6,17,18}, {6,18,9}, {9,18,21}, {9,21,10}, {10,21,22} + }; + } + else { + std::vector vertices = get_vertices(z_upper, z_lower, nar_upper_x, nar_lower_x, ext_upper_x, ext_lower_x); + mesh.vertices.insert(mesh.vertices.end(), vertices.begin(), vertices.end()); + + mesh.indices = { + // above view + {5,4,7}, {5,7,6}, // lower part + {3,4,2}, {2,4,5}, // left side + {9,6,8}, {8,6,7}, // right side + {1,0,2}, {2,0,3}, // upper left part + {9,8,10}, {10,8,11}, // upper right part + // under view + {16,15,14}, {16,14,17}, // left side + {18,21,20}, {18,20,19}, // right side + {16,17,18}, {16,18,19} // lower part + }; + } + return mesh; + } + + float cross_pt_upper_y = groove_half_width_upper / tan(m_groove_angle); + + // groove is closed + + if (groove_half_width_upper < proj && groove_half_width_lower < proj) { + float cross_pt_lower_y = groove_half_width_lower / tan(m_groove_angle); + + indexed_triangle_set mesh; + + auto get_vertices = [x, y](float z_upper, float z_lower, float cross_pt_upper_y, float cross_pt_lower_y, float ext_upper_x, float ext_lower_x) { + return std::vector({ + // upper part vertices + {-x, -y, z_upper}, {-x, y, z_upper}, {x, y, z_upper}, {x, -y, z_upper}, + {ext_upper_x, -y, z_upper}, {0.f, cross_pt_upper_y, z_upper}, {-ext_upper_x, -y, z_upper}, + // lower part vertices + {-ext_lower_x, -y, z_lower}, {0.f, cross_pt_lower_y, z_lower}, {ext_lower_x, -y, z_lower} + }); + }; + + mesh.vertices = get_vertices(z_upper, z_lower, cross_pt_upper_y, cross_pt_lower_y, ext_upper_x, ext_lower_x); + mesh.vertices.reserve(2 * mesh.vertices.size()); + + z_upper -= cut_plane_thiknes; + z_lower -= cut_plane_thiknes; + + if (m_use_TAG_mesh_full) { + const float under_x_shift = cut_plane_thiknes / tan(0.5f * m_groove_flaps_angle); + + cross_pt_upper_y += cut_plane_thiknes; + cross_pt_lower_y += cut_plane_thiknes; + ext_upper_x += under_x_shift; + ext_lower_x += under_x_shift; + + std::vector vertices = get_vertices(z_upper, z_lower, cross_pt_upper_y, cross_pt_lower_y, ext_upper_x, ext_lower_x); + mesh.vertices.insert(mesh.vertices.end(), vertices.begin(), vertices.end()); + + mesh.indices = { + // above view + {8,7,9}, // lower part + {5,8,6}, {6,8,7}, // left side + {4,9,8}, {4,8,5}, // right side + {1,0,6}, {1,6,5},{1,5,2}, {2,5,4}, {2,4,3}, // upper part + // under view + {10,11,16}, {16,11,15}, {15,11,12}, {15,12,14}, {14,12,13}, // upper part + {18,15,14}, {14,18,19}, // right side + {17,16,15}, {17,15,18}, // left side + {17,18,19}, // lower part + // left edge + {1,11,0}, {0,11,10}, + // front edge + {0,10,6}, {6,10,16}, {6,17,16}, {6,7,17}, {7,17,19}, {7,19,9}, {4,14,19}, {4,19,9}, {4,14,13}, {4,13,3}, + // right edge + {3,13,12}, {3,12,2}, + // back edge + {2,12,11}, {2,11,1} + }; + } + else { + std::vector vertices = get_vertices(z_upper, z_lower, cross_pt_upper_y, cross_pt_lower_y, ext_upper_x, ext_lower_x); + mesh.vertices.insert(mesh.vertices.end(), vertices.begin(), vertices.end()); + + mesh.indices = { + // above view + {8,7,9}, // lower part + {5,8,6}, {6,8,7}, // left side + {4,9,8}, {4,8,5}, // right side + {1,0,6}, {1,6,5},{1,5,2}, {2,5,4}, {2,4,3}, // upper part + // under view + {18,15,14}, {14,18,19}, // right side + {17,16,15}, {17,15,18}, // left side + {17,18,19}, // lower part + }; + } + return mesh; + + } + + // groove is closed from the roof + + indexed_triangle_set mesh; + mesh.vertices = { + // upper part vertices + {-x, -y, z_upper}, {-x, y, z_upper}, {x, y, z_upper}, {x, -y, z_upper}, + {ext_upper_x, -y, z_upper}, {0.f, cross_pt_upper_y, z_upper}, {-ext_upper_x, -y, z_upper}, + // lower part vertices + {-ext_lower_x, -y, z_lower}, {-nar_lower_x, y, z_lower}, {nar_lower_x, y, z_lower}, {ext_lower_x, -y, z_lower} + }; + + mesh.vertices.reserve(2 * mesh.vertices.size() + 1); + + z_upper -= cut_plane_thiknes; + z_lower -= cut_plane_thiknes; + + const float under_x_shift = cut_plane_thiknes / tan(0.5f * m_groove_flaps_angle); + + nar_lower_x += under_x_shift; + ext_upper_x += under_x_shift; + ext_lower_x += under_x_shift; + + std::vector vertices = { + // upper part vertices + {-x, -y, z_upper}, {-x, y, z_upper}, {x, y, z_upper}, {x, -y, z_upper}, + {ext_upper_x, -y, z_upper}, {under_x_shift, cross_pt_upper_y, z_upper}, {-under_x_shift, cross_pt_upper_y, z_upper}, {-ext_upper_x, -y, z_upper}, + // lower part vertices + {-ext_lower_x, -y, z_lower}, {-nar_lower_x, y, z_lower}, {nar_lower_x, y, z_lower}, {ext_lower_x, -y, z_lower} + }; + mesh.vertices.insert(mesh.vertices.end(), vertices.begin(), vertices.end()); + + if (m_use_TAG_mesh_full) { + mesh.indices = { + // above view + {8,7,10}, {8,10,9}, // lower part + {5,8,7}, {5,7,6}, // left side + {4,10,9}, {4,9,5}, // right side + {1,0,6}, {1,6,5},{1,5,2}, {2,5,4}, {2,4,3}, // upper part + // under view + {11,12,18}, {18,12,17}, {17,12,16}, {16,12,13}, {16,13,15}, {15,13,14}, // upper part + {21,16,15}, {21,15,22}, // right side + {19,18,17}, {19,17,20}, // left side + {19,20,21}, {19,21,22}, // lower part + // left edge + {1,12,11}, {1,11,0}, + // front edge + {0,11,18}, {0,18,6}, {7,19,18}, {7,18,6}, {7,19,22}, {7,22,10}, {10,22,15}, {10,15,4}, {4,15,14}, {4,14,3}, + // right edge + {3,14,13}, {3,14,2}, + // back edge + {2,13,12}, {2,12,1}, {5,16,21}, {5,21,9}, {9,21,20}, {9,20,8}, {5,17,20}, {5,20,8} + }; + } + else { + mesh.indices = { + // above view + {8,7,10}, {8,10,9}, // lower part + {5,8,7}, {5,7,6}, // left side + {4,10,9}, {4,9,5}, // right side + {1,0,6}, {1,6,5}, {1,5,2}, {2,5,4}, {2,4,3}, // upper part + // under view + {21,16,15}, {21,15,22}, // right side + {19,18,17}, {19,17,20}, // left side + {19,20,21}, {19,21,22}, // lower part + }; + } + + return mesh; +} + void GLGizmoCut3D::render_cut_plate_for_tongue_and_groove(GLShaderProgram* shader) { const Camera & camera = wxGetApp().plater()->get_camera(); @@ -925,6 +1187,17 @@ void GLGizmoCut3D::render_cut_plane() shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + if (m_use_TAG_mesh) { + ColorRGBA cp_clr = can_perform_cut() && has_valid_contour() ? CUT_PLANE_DEF_COLOR : CUT_PLANE_ERR_COLOR; + if (m_mode == size_t(CutMode::cutTongueAndGroove)) + cp_clr.a(cp_clr.a() - 0.1f); + m_plane.model.set_color(cp_clr); + + const Transform3d view_model_matrix = camera.get_view_matrix() * translation_transform(m_plane_center) * m_rotation_m; + shader->set_uniform("view_model_matrix", view_model_matrix); + m_plane.model.render(); + } + else { m_plane.model.set_color(can_perform_cut() && has_valid_contour() ? CUT_PLANE_DEF_COLOR : CUT_PLANE_ERR_COLOR); if (m_mode == size_t(CutMode::cutPlanar)) { @@ -934,7 +1207,7 @@ void GLGizmoCut3D::render_cut_plane() } else if (m_mode == size_t(CutMode::cutTongueAndGroove)) render_cut_plate_for_tongue_and_groove(shader); - + } glsafe(::glEnable(GL_CULL_FACE)); glsafe(::glDisable(GL_BLEND)); @@ -1731,7 +2004,7 @@ void GLGizmoCut3D::update_bb() // input params for cut with tongue and groove m_groove_depth = m_groove_depth_init = 0.5f * float(get_grabber_mean_size(m_bounding_box)); m_groove_width = m_groove_width_init = 4.0f * m_groove_depth; - m_groove_flaps_angle = m_groove_flaps_angle_init = float(PI) / 3.f;// 0.25f * float(PI); + m_groove_flaps_angle = m_groove_flaps_angle_init = float(PI) / 3.f; m_groove_angle = m_groove_angle_init = 0.f; m_plane.reset(); m_cone.reset(); @@ -1768,7 +2041,13 @@ void GLGizmoCut3D::init_picking_models() if (!m_plane.model.is_initialized() && !m_hide_cut_plane && !m_connectors_editing) { const double cp_width = 0.02 * get_grabber_mean_size(m_bounding_box); - indexed_triangle_set its = its_make_frustum_dowel((double)m_cut_plane_radius_koef * m_radius, cp_width, m_cut_plane_as_circle ? 180 : 4); + indexed_triangle_set its; + if (m_use_TAG_mesh) + its = m_mode == size_t(CutMode::cutTongueAndGroove) ? its_make_groove_plane() : + its_make_frustum_dowel((double)m_cut_plane_radius_koef * m_radius, cp_width, m_cut_plane_as_circle ? 180 : 4); + else + its = its_make_frustum_dowel((double)m_cut_plane_radius_koef * m_radius, cp_width, m_cut_plane_as_circle ? 180 : 4); + m_plane.model.init_from(its); m_plane.mesh_raycaster = std::make_unique(std::make_shared(std::move(its))); } @@ -2097,12 +2376,23 @@ void GLGizmoCut3D::on_render() void GLGizmoCut3D::render_debug_input_window(float x) { - return; m_imgui->begin(wxString("DEBUG")); ImVec2 pos = ImGui::GetWindowPos(); pos.x = x; ImGui::SetWindowPos(pos, ImGuiCond_Always); + + bool is_changed = m_imgui->checkbox(("Render Cut plane as a one mesh"), m_use_TAG_mesh); + is_changed |= m_imgui->checkbox(("Render Cut plane as a full mesh"), m_use_TAG_mesh_full); + + if (is_changed) + { + m_plane.reset(); + on_unregister_raycasters_for_picking(); + } + + m_imgui->end(); + return; /* static bool hide_clipped = false; static bool fill_cut = false; @@ -2483,6 +2773,10 @@ void GLGizmoCut3D::render_groove_float_input(const std::string& label, float& in m_imgui->disabled_end(); if (is_changed) { + if (m_use_TAG_mesh) { + m_plane.reset(); + on_unregister_raycasters_for_picking(); + } reset_cut_by_contours(); // Plater::TakeSnapshot snapshot(wxGetApp().plater(), format_wxstr("%1%: %2%", _L("Groove change"), label), UndoRedo::SnapshotType::GizmoAction); } @@ -2519,6 +2813,10 @@ void GLGizmoCut3D::render_groove_angle_input(const std::string& label, float& in m_imgui->disabled_end(); if (is_changed) { + if (m_use_TAG_mesh) { + m_plane.reset(); + on_unregister_raycasters_for_picking(); + } reset_cut_by_contours(); // Plater::TakeSnapshot snapshot(wxGetApp().plater(), format_wxstr("%1%: %2%", _L("Groove change"), label), UndoRedo::SnapshotType::GizmoAction); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 30663a99c7..d611dca63c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -235,6 +235,11 @@ class GLGizmoCut3D : public GLGizmoBase std::map m_labels_map; + // Debug values + bool m_use_TAG_mesh {true}; + bool m_use_TAG_mesh_full {true}; + // + public: GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); @@ -376,6 +381,7 @@ private: indexed_triangle_set its_make_upper_groove_plane(); indexed_triangle_set its_make_lower_groove_plane(float flaps_width); indexed_triangle_set its_make_sides_groove_plane(float flaps_width); + indexed_triangle_set its_make_groove_plane(); indexed_triangle_set get_connector_mesh(CutConnectorAttributes connector_attributes); void apply_cut_connectors(ModelObject* mo, const std::string& connector_name);