mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-23 06:33:57 -06:00
Reworked visualization of selected triangles by seed fill and bucket fill inside the multi-material painting gizmo. Now is drawn boundary around a selected area, and also all triangles inside the selected area are drawn with a darker color.
This commit is contained in:
parent
e5ce748b10
commit
18cff61bd2
8 changed files with 239 additions and 34 deletions
|
@ -336,8 +336,6 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(max_tooltip_width);
|
||||
|
@ -467,7 +465,12 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||
"placed after the number with no whitespace in between.");
|
||||
ImGui::SameLine(sliders_width);
|
||||
ImGui::PushItemWidth(window_width - sliders_width);
|
||||
m_imgui->slider_float("##seed_fill_angle", &m_seed_fill_angle, SeedFillAngleMin, SeedFillAngleMax, format_str.data());
|
||||
if(m_imgui->slider_float("##seed_fill_angle", &m_seed_fill_angle, SeedFillAngleMin, SeedFillAngleMax, format_str.data()))
|
||||
for (auto &triangle_selector : m_triangle_selectors) {
|
||||
triangle_selector->seed_fill_unselect_all_triangles();
|
||||
triangle_selector->request_update_render_data();
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(max_tooltip_width);
|
||||
|
@ -594,10 +597,13 @@ std::array<float, 4> GLGizmoMmuSegmentation::get_cursor_sphere_right_button_colo
|
|||
return {color[0], color[1], color[2], 0.25f};
|
||||
}
|
||||
|
||||
static std::array<float, 4> get_seed_fill_color(const std::array<float, 4> &base_color)
|
||||
{
|
||||
return {base_color[0] * 0.75f, base_color[1] * 0.75f, base_color[2] * 0.75f, 1.f};
|
||||
}
|
||||
|
||||
void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
|
||||
{
|
||||
static constexpr std::array<float, 4> seed_fill_color{0.f, 1.f, 0.44f, 1.f};
|
||||
|
||||
if (m_update_render_data)
|
||||
update_render_data();
|
||||
|
||||
|
@ -610,12 +616,24 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
|
|||
|
||||
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx)
|
||||
if (m_gizmo_scene.has_VBOs(color_idx)) {
|
||||
shader->set_uniform("uniform_color", color_idx == 0 ? m_default_volume_color :
|
||||
color_idx == (m_gizmo_scene.triangle_indices.size() - 1) ? seed_fill_color :
|
||||
m_colors[color_idx - 1]);
|
||||
if (color_idx > m_colors.size()) // Seed fill VBO
|
||||
shader->set_uniform("uniform_color", get_seed_fill_color(color_idx == (m_colors.size() + 1) ? m_default_volume_color : m_colors[color_idx - (m_colors.size() + 1) - 1]));
|
||||
else // Normal VBO
|
||||
shader->set_uniform("uniform_color", color_idx == 0 ? m_default_volume_color : m_colors[color_idx - 1]);
|
||||
|
||||
m_gizmo_scene.render(color_idx);
|
||||
}
|
||||
|
||||
if (m_gizmo_scene.has_contour_VBO()) {
|
||||
ScopeGuard guard_gouraud([shader]() { shader->start_using(); });
|
||||
shader->stop_using();
|
||||
|
||||
auto *contour_shader = wxGetApp().get_shader("mm_contour");
|
||||
contour_shader->start_using();
|
||||
m_gizmo_scene.render_contour();
|
||||
contour_shader->stop_using();
|
||||
}
|
||||
|
||||
m_update_render_data = false;
|
||||
}
|
||||
|
||||
|
@ -632,10 +650,10 @@ void TriangleSelectorMmGui::update_render_data()
|
|||
|
||||
for (const Triangle &tr : m_triangles)
|
||||
if (tr.valid() && !tr.is_split()) {
|
||||
int color = int(tr.get_state());
|
||||
std::vector<int> &iva = tr.is_selected_by_seed_fill() ? m_gizmo_scene.triangle_indices.back() :
|
||||
color < int(m_gizmo_scene.triangle_indices.size() - 1) ? m_gizmo_scene.triangle_indices[color] :
|
||||
m_gizmo_scene.triangle_indices.front();
|
||||
int color = int(tr.get_state()) <= int(m_colors.size()) ? int(tr.get_state()) : 0;
|
||||
assert(m_colors.size() + 1 + color < m_gizmo_scene.triangle_indices.size());
|
||||
std::vector<int> &iva = m_gizmo_scene.triangle_indices[color + tr.is_selected_by_seed_fill() * (m_colors.size() + 1)];
|
||||
|
||||
if (iva.size() + 3 > iva.capacity())
|
||||
iva.reserve(next_highest_power_of_2(iva.size() + 3));
|
||||
|
||||
|
@ -648,6 +666,24 @@ void TriangleSelectorMmGui::update_render_data()
|
|||
m_gizmo_scene.triangle_indices_sizes[color_idx] = m_gizmo_scene.triangle_indices[color_idx].size();
|
||||
|
||||
m_gizmo_scene.finalize_triangle_indices();
|
||||
|
||||
std::vector<Vec2i> contour_edges = this->get_seed_fill_contour();
|
||||
m_gizmo_scene.contour_vertices.reserve(contour_edges.size() * 6);
|
||||
for (const Vec2i &edge : contour_edges) {
|
||||
m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(0)].v.x());
|
||||
m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(0)].v.y());
|
||||
m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(0)].v.z());
|
||||
|
||||
m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(1)].v.x());
|
||||
m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(1)].v.y());
|
||||
m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(1)].v.z());
|
||||
}
|
||||
|
||||
m_gizmo_scene.contour_indices.assign(m_gizmo_scene.contour_vertices.size() / 3, 0);
|
||||
std::iota(m_gizmo_scene.contour_indices.begin(), m_gizmo_scene.contour_indices.end(), 0);
|
||||
m_gizmo_scene.contour_indices_size = m_gizmo_scene.contour_indices.size();
|
||||
|
||||
m_gizmo_scene.finalize_contour();
|
||||
}
|
||||
|
||||
wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const
|
||||
|
@ -671,6 +707,14 @@ void GLMmSegmentationGizmo3DScene::release_geometry() {
|
|||
glsafe(::glDeleteBuffers(1, &triangle_indices_VBO_id));
|
||||
triangle_indices_VBO_id = 0;
|
||||
}
|
||||
if (this->contour_vertices_VBO_id) {
|
||||
glsafe(::glDeleteBuffers(1, &this->contour_vertices_VBO_id));
|
||||
this->contour_vertices_VBO_id = 0;
|
||||
}
|
||||
if (this->contour_indices_VBO_id) {
|
||||
glsafe(::glDeleteBuffers(1, &this->contour_indices_VBO_id));
|
||||
this->contour_indices_VBO_id = 0;
|
||||
}
|
||||
this->clear();
|
||||
}
|
||||
|
||||
|
@ -681,6 +725,10 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
|
|||
assert(this->vertices_VBO_id != 0);
|
||||
assert(this->triangle_indices_VBO_ids[triangle_indices_idx] != 0);
|
||||
|
||||
ScopeGuard offset_fill_guard([]() { glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); });
|
||||
glsafe(::glEnable(GL_POLYGON_OFFSET_FILL));
|
||||
glsafe(::glPolygonOffset(5.0, 5.0));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
|
||||
|
||||
|
@ -698,13 +746,36 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
|
|||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
||||
void GLMmSegmentationGizmo3DScene::render_contour() const
|
||||
{
|
||||
assert(this->contour_vertices_VBO_id != 0);
|
||||
assert(this->contour_indices_VBO_id != 0);
|
||||
|
||||
glsafe(::glLineWidth(4.0f));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->contour_vertices_VBO_id));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), nullptr));
|
||||
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
if (this->contour_indices_size > 0) {
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->contour_indices_VBO_id));
|
||||
glsafe(::glDrawElements(GL_LINES, GLsizei(this->contour_indices_size), GL_UNSIGNED_INT, nullptr));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
||||
void GLMmSegmentationGizmo3DScene::finalize_vertices()
|
||||
{
|
||||
assert(this->vertices_VBO_id == 0);
|
||||
if (!this->vertices.empty()) {
|
||||
glsafe(::glGenBuffers(1, &this->vertices_VBO_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * 4, this->vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(float), this->vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
this->vertices.clear();
|
||||
}
|
||||
|
@ -719,19 +790,32 @@ void GLMmSegmentationGizmo3DScene::finalize_triangle_indices()
|
|||
if (!this->triangle_indices[buffer_idx].empty()) {
|
||||
glsafe(::glGenBuffers(1, &this->triangle_indices_VBO_ids[buffer_idx]));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_ids[buffer_idx]));
|
||||
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices[buffer_idx].size() * 4, this->triangle_indices[buffer_idx].data(),
|
||||
GL_STATIC_DRAW));
|
||||
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices[buffer_idx].size() * sizeof(int), this->triangle_indices[buffer_idx].data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
this->triangle_indices[buffer_idx].clear();
|
||||
}
|
||||
}
|
||||
|
||||
void GLMmSegmentationGizmo3DScene::finalize_geometry()
|
||||
void GLMmSegmentationGizmo3DScene::finalize_contour()
|
||||
{
|
||||
assert(this->vertices_VBO_id == 0);
|
||||
assert(this->triangle_indices.size() == this->triangle_indices_VBO_ids.size());
|
||||
finalize_vertices();
|
||||
finalize_triangle_indices();
|
||||
assert(this->contour_vertices_VBO_id == 0);
|
||||
assert(this->contour_indices_VBO_id == 0);
|
||||
|
||||
if (!this->contour_vertices.empty()) {
|
||||
glsafe(::glGenBuffers(1, &this->contour_vertices_VBO_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->contour_vertices_VBO_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->contour_vertices.size() * sizeof(float), this->contour_vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
this->contour_vertices.clear();
|
||||
}
|
||||
|
||||
if (!this->contour_indices.empty()) {
|
||||
glsafe(::glGenBuffers(1, &this->contour_indices_VBO_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->contour_indices_VBO_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->contour_indices.size() * sizeof(unsigned int), this->contour_indices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
this->contour_indices.clear();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue