mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 16:51:21 -06:00
Fixed conflicts after pulling from master
This commit is contained in:
commit
56e2f47ba6
29 changed files with 1743 additions and 565 deletions
|
|
@ -39,26 +39,22 @@ enum ModelInstanceEPrintVolumeState : unsigned char;
|
|||
// possibly indexed by triangles and / or quads.
|
||||
class GLIndexedVertexArray {
|
||||
public:
|
||||
GLIndexedVertexArray() :
|
||||
vertices_and_normals_interleaved_VBO_id(0),
|
||||
triangle_indices_VBO_id(0),
|
||||
quad_indices_VBO_id(0)
|
||||
{}
|
||||
// Only Eigen types of Nx16 size are vectorized. This bounding box will not be vectorized.
|
||||
static_assert(sizeof(Eigen::AlignedBox<float, 3>) == 24, "Eigen::AlignedBox<float, 3> is not being vectorized, thus it does not need to be aligned");
|
||||
using BoundingBox = Eigen::AlignedBox<float, 3>;
|
||||
|
||||
GLIndexedVertexArray() { m_bounding_box.setEmpty(); }
|
||||
GLIndexedVertexArray(const GLIndexedVertexArray &rhs) :
|
||||
vertices_and_normals_interleaved(rhs.vertices_and_normals_interleaved),
|
||||
triangle_indices(rhs.triangle_indices),
|
||||
quad_indices(rhs.quad_indices),
|
||||
vertices_and_normals_interleaved_VBO_id(0),
|
||||
triangle_indices_VBO_id(0),
|
||||
quad_indices_VBO_id(0)
|
||||
{ assert(! rhs.has_VBOs()); }
|
||||
m_bounding_box(rhs.m_bounding_box)
|
||||
{ assert(! rhs.has_VBOs()); m_bounding_box.setEmpty(); }
|
||||
GLIndexedVertexArray(GLIndexedVertexArray &&rhs) :
|
||||
vertices_and_normals_interleaved(std::move(rhs.vertices_and_normals_interleaved)),
|
||||
triangle_indices(std::move(rhs.triangle_indices)),
|
||||
quad_indices(std::move(rhs.quad_indices)),
|
||||
vertices_and_normals_interleaved_VBO_id(0),
|
||||
triangle_indices_VBO_id(0),
|
||||
quad_indices_VBO_id(0)
|
||||
m_bounding_box(rhs.m_bounding_box)
|
||||
{ assert(! rhs.has_VBOs()); }
|
||||
|
||||
~GLIndexedVertexArray() { release_geometry(); }
|
||||
|
|
@ -92,7 +88,7 @@ public:
|
|||
this->vertices_and_normals_interleaved = std::move(rhs.vertices_and_normals_interleaved);
|
||||
this->triangle_indices = std::move(rhs.triangle_indices);
|
||||
this->quad_indices = std::move(rhs.quad_indices);
|
||||
this->m_bounding_box = std::move(rhs.m_bounding_box);
|
||||
this->m_bounding_box = rhs.m_bounding_box;
|
||||
this->vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size;
|
||||
this->triangle_indices_size = rhs.triangle_indices_size;
|
||||
this->quad_indices_size = rhs.quad_indices_size;
|
||||
|
|
@ -147,7 +143,7 @@ public:
|
|||
this->vertices_and_normals_interleaved.emplace_back(z);
|
||||
|
||||
this->vertices_and_normals_interleaved_size = this->vertices_and_normals_interleaved.size();
|
||||
m_bounding_box.merge(Vec3f(x, y, z).cast<double>());
|
||||
m_bounding_box.extend(Vec3f(x, y, z));
|
||||
};
|
||||
|
||||
inline void push_geometry(double x, double y, double z, double nx, double ny, double nz) {
|
||||
|
|
@ -203,10 +199,10 @@ public:
|
|||
this->vertices_and_normals_interleaved.clear();
|
||||
this->triangle_indices.clear();
|
||||
this->quad_indices.clear();
|
||||
this->m_bounding_box.reset();
|
||||
vertices_and_normals_interleaved_size = 0;
|
||||
triangle_indices_size = 0;
|
||||
quad_indices_size = 0;
|
||||
m_bounding_box.setEmpty();
|
||||
}
|
||||
|
||||
// Shrink the internal storage to tighly fit the data stored.
|
||||
|
|
@ -216,7 +212,7 @@ public:
|
|||
this->quad_indices.shrink_to_fit();
|
||||
}
|
||||
|
||||
const BoundingBoxf3& bounding_box() const { return m_bounding_box; }
|
||||
const BoundingBox& bounding_box() const { return m_bounding_box; }
|
||||
|
||||
// Return an estimate of the memory consumed by this class.
|
||||
size_t cpu_memory_used() const { return sizeof(*this) + vertices_and_normals_interleaved.capacity() * sizeof(float) + triangle_indices.capacity() * sizeof(int) + quad_indices.capacity() * sizeof(int); }
|
||||
|
|
@ -235,7 +231,7 @@ public:
|
|||
size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); }
|
||||
|
||||
private:
|
||||
BoundingBoxf3 m_bounding_box;
|
||||
BoundingBox m_bounding_box;
|
||||
};
|
||||
|
||||
class GLVolume {
|
||||
|
|
@ -355,7 +351,15 @@ public:
|
|||
std::vector<size_t> offsets;
|
||||
|
||||
// Bounding box of this volume, in unscaled coordinates.
|
||||
const BoundingBoxf3& bounding_box() const { return this->indexed_vertex_array.bounding_box(); }
|
||||
BoundingBoxf3 bounding_box() const {
|
||||
BoundingBoxf3 out;
|
||||
if (! this->indexed_vertex_array.bounding_box().isEmpty()) {
|
||||
out.min = this->indexed_vertex_array.bounding_box().min().cast<double>();
|
||||
out.max = this->indexed_vertex_array.bounding_box().max().cast<double>();
|
||||
out.defined = true;
|
||||
};
|
||||
return out;
|
||||
}
|
||||
|
||||
void set_render_color(float r, float g, float b, float a);
|
||||
void set_render_color(const float* rgba, unsigned int size);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
|
|
@ -14,6 +15,7 @@
|
|||
#include <wx/statbox.h>
|
||||
#include <wx/wupdlock.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/listctrl.h>
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
|
|
@ -148,32 +150,32 @@ void GalleryDialog::on_dpi_changed(const wxRect& suggested_rect)
|
|||
Refresh();
|
||||
}
|
||||
|
||||
static void add_border(wxImage& image)
|
||||
{
|
||||
const wxColour& clr = wxGetApp().get_color_hovered_btn_label();
|
||||
//static void add_border(wxImage& image)
|
||||
//{
|
||||
// const wxColour& clr = wxGetApp().get_color_hovered_btn_label();
|
||||
|
||||
auto px_data = (uint8_t*)image.GetData();
|
||||
auto a_data = (uint8_t*)image.GetAlpha();
|
||||
// auto px_data = (uint8_t*)image.GetData();
|
||||
// auto a_data = (uint8_t*)image.GetAlpha();
|
||||
|
||||
int width = image.GetWidth();
|
||||
int height = image.GetHeight();
|
||||
int border_width = 1;
|
||||
// int width = image.GetWidth();
|
||||
// int height = image.GetHeight();
|
||||
// int border_width = 1;
|
||||
|
||||
for (size_t x = 0; x < width; ++x) {
|
||||
for (size_t y = 0; y < height; ++y) {
|
||||
if (x < border_width || y < border_width ||
|
||||
x >= (width - border_width) || y >= (height - border_width)) {
|
||||
const size_t idx = (x + y * width);
|
||||
const size_t idx_rgb = (x + y * width) * 3;
|
||||
px_data[idx_rgb] = clr.Red();
|
||||
px_data[idx_rgb + 1] = clr.Green();
|
||||
px_data[idx_rgb + 2] = clr.Blue();
|
||||
if (a_data)
|
||||
a_data[idx] = 255u;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (size_t x = 0; x < width; ++x) {
|
||||
// for (size_t y = 0; y < height; ++y) {
|
||||
// if (x < border_width || y < border_width ||
|
||||
// x >= (width - border_width) || y >= (height - border_width)) {
|
||||
// const size_t idx = (x + y * width);
|
||||
// const size_t idx_rgb = (x + y * width) * 3;
|
||||
// px_data[idx_rgb] = clr.Red();
|
||||
// px_data[idx_rgb + 1] = clr.Green();
|
||||
// px_data[idx_rgb + 2] = clr.Blue();
|
||||
// if (a_data)
|
||||
// a_data[idx] = 255u;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
static void add_lock(wxImage& image)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
class wxListCtrl;
|
||||
class wxImageList;
|
||||
class wxListEvent;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
if (mv->is_model_part()) {
|
||||
++idx;
|
||||
m_triangle_selectors[idx]->reset();
|
||||
m_triangle_selectors[idx]->request_update_render_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,13 +286,12 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block)
|
|||
|
||||
// Now calculate dot product of vert_direction and facets' normals.
|
||||
int idx = -1;
|
||||
for (const stl_facet& facet : mv->mesh().stl.facet_start) {
|
||||
for (const stl_facet &facet : mv->mesh().stl.facet_start) {
|
||||
++idx;
|
||||
if (facet.normal.dot(down) > dot_limit)
|
||||
m_triangle_selectors[mesh_id]->set_facet(idx,
|
||||
block
|
||||
? EnforcerBlockerType::BLOCKER
|
||||
: EnforcerBlockerType::ENFORCER);
|
||||
if (facet.normal.dot(down) > dot_limit) {
|
||||
m_triangle_selectors[mesh_id]->set_facet(idx, block ? EnforcerBlockerType::BLOCKER : EnforcerBlockerType::ENFORCER);
|
||||
m_triangle_selectors.back()->request_update_render_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -346,6 +346,7 @@ void GLGizmoFdmSupports::update_from_model_object()
|
|||
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorGUI>(*mesh));
|
||||
m_triangle_selectors.back()->deserialize(mv->supported_facets.get_data());
|
||||
m_triangle_selectors.back()->request_update_render_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -296,8 +296,10 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||
|
||||
if (m_imgui->checkbox(_L("Seed fill"), m_seed_fill_enabled))
|
||||
if (!m_seed_fill_enabled)
|
||||
for (auto &triangle_selector : m_triangle_selectors)
|
||||
for (auto &triangle_selector : m_triangle_selectors) {
|
||||
triangle_selector->seed_fill_unselect_all_triangles();
|
||||
triangle_selector->request_update_render_data();
|
||||
}
|
||||
|
||||
m_imgui->text(m_desc["seed_fill_angle"] + ":");
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
|
@ -319,6 +321,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||
if (mv->is_model_part()) {
|
||||
++idx;
|
||||
m_triangle_selectors[idx]->reset();
|
||||
m_triangle_selectors[idx]->request_update_render_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -437,8 +440,9 @@ void GLGizmoMmuSegmentation::init_model_triangle_selectors()
|
|||
const TriangleMesh *mesh = &mv->mesh();
|
||||
|
||||
int extruder_idx = (mv->extruder_id() > 0) ? mv->extruder_id() - 1 : 0;
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorMmuGui>(*mesh, m_modified_extruders_colors, m_original_extruders_colors[size_t(extruder_idx)]));
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorMmGui>(*mesh, m_modified_extruders_colors, m_original_extruders_colors[size_t(extruder_idx)]));
|
||||
m_triangle_selectors.back()->deserialize(mv->mmu_segmentation_facets.get_data());
|
||||
m_triangle_selectors.back()->request_update_render_data();
|
||||
}
|
||||
m_original_volumes_extruder_idxs = get_extruder_id_for_volumes(*mo);
|
||||
}
|
||||
|
|
@ -466,56 +470,60 @@ std::array<float, 4> GLGizmoMmuSegmentation::get_cursor_sphere_right_button_colo
|
|||
return {color[0], color[1], color[2], 0.25f};
|
||||
}
|
||||
|
||||
void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui)
|
||||
void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
|
||||
{
|
||||
static constexpr std::array<float, 4> seed_fill_color{0.f, 1.f, 0.44f, 1.f};
|
||||
|
||||
std::vector<int> color_cnt(m_iva_colors.size());
|
||||
int seed_fill_cnt = 0;
|
||||
for (auto &iva_color : m_iva_colors)
|
||||
iva_color.release_geometry();
|
||||
m_iva_seed_fill.release_geometry();
|
||||
|
||||
auto append_triangle = [this](GLIndexedVertexArray &iva, int &cnt, const Triangle &tr) -> void {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
iva.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal);
|
||||
iva.push_triangle(cnt, cnt + 1, cnt + 2);
|
||||
cnt += 3;
|
||||
};
|
||||
|
||||
for (size_t color_idx = 0; color_idx < m_iva_colors.size(); ++color_idx) {
|
||||
for (const Triangle &tr : m_triangles) {
|
||||
if (!tr.valid() || tr.is_split() || tr.is_selected_by_seed_fill() || tr.get_state() != EnforcerBlockerType(color_idx))
|
||||
continue;
|
||||
append_triangle(m_iva_colors[color_idx], color_cnt[color_idx], tr);
|
||||
}
|
||||
}
|
||||
|
||||
for (const Triangle &tr : m_triangles) {
|
||||
if (!tr.valid() || tr.is_split() || !tr.is_selected_by_seed_fill())
|
||||
continue;
|
||||
append_triangle(m_iva_seed_fill, seed_fill_cnt, tr);
|
||||
}
|
||||
|
||||
for (auto &iva_color : m_iva_colors)
|
||||
iva_color.finalize_geometry(true);
|
||||
m_iva_seed_fill.finalize_geometry(true);
|
||||
if (m_update_render_data)
|
||||
update_render_data();
|
||||
|
||||
auto *shader = wxGetApp().get_current_shader();
|
||||
if (!shader)
|
||||
return;
|
||||
assert(shader->get_name() == "gouraud");
|
||||
ScopeGuard guard([shader]() { if (shader) shader->set_uniform("compute_triangle_normals_in_fs", false);});
|
||||
shader->set_uniform("compute_triangle_normals_in_fs", true);
|
||||
|
||||
auto render = [&shader](const GLIndexedVertexArray &iva, const std::array<float, 4> &color) -> void {
|
||||
if (iva.has_VBOs()) {
|
||||
shader->set_uniform("uniform_color", color);
|
||||
iva.render();
|
||||
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]);
|
||||
m_gizmo_scene.render(color_idx);
|
||||
}
|
||||
};
|
||||
|
||||
for (size_t color_idx = 0; color_idx < m_iva_colors.size(); ++color_idx)
|
||||
render(m_iva_colors[color_idx], (color_idx == 0) ? m_default_volume_color : m_colors[color_idx - 1]);
|
||||
render(m_iva_seed_fill, seed_fill_color);
|
||||
m_update_render_data = false;
|
||||
}
|
||||
|
||||
void TriangleSelectorMmGui::update_render_data()
|
||||
{
|
||||
m_gizmo_scene.release_geometry();
|
||||
m_vertices.reserve(m_vertices.size() * 3);
|
||||
for (const Vertex &vr : m_vertices) {
|
||||
m_gizmo_scene.vertices.emplace_back(vr.v.x());
|
||||
m_gizmo_scene.vertices.emplace_back(vr.v.y());
|
||||
m_gizmo_scene.vertices.emplace_back(vr.v.z());
|
||||
}
|
||||
m_gizmo_scene.finalize_vertices();
|
||||
|
||||
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();
|
||||
if (iva.size() + 3 > iva.capacity())
|
||||
iva.reserve(next_highest_power_of_2(iva.size() + 3));
|
||||
|
||||
iva.emplace_back(tr.verts_idxs[0]);
|
||||
iva.emplace_back(tr.verts_idxs[1]);
|
||||
iva.emplace_back(tr.verts_idxs[2]);
|
||||
}
|
||||
|
||||
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx)
|
||||
m_gizmo_scene.triangle_indices_sizes[color_idx] = m_gizmo_scene.triangle_indices[color_idx].size();
|
||||
|
||||
m_gizmo_scene.finalize_triangle_indices();
|
||||
}
|
||||
|
||||
wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const
|
||||
|
|
@ -530,4 +538,77 @@ wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GL
|
|||
return action_name;
|
||||
}
|
||||
|
||||
void GLMmSegmentationGizmo3DScene::release_geometry() {
|
||||
if (this->vertices_VBO_id) {
|
||||
glsafe(::glDeleteBuffers(1, &this->vertices_VBO_id));
|
||||
this->vertices_VBO_id = 0;
|
||||
}
|
||||
for(auto &triangle_indices_VBO_id : triangle_indices_VBO_ids) {
|
||||
glsafe(::glDeleteBuffers(1, &triangle_indices_VBO_id));
|
||||
triangle_indices_VBO_id = 0;
|
||||
}
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
|
||||
{
|
||||
assert(triangle_indices_idx < this->triangle_indices_VBO_ids.size());
|
||||
assert(this->triangle_indices_sizes.size() == this->triangle_indices_VBO_ids.size());
|
||||
assert(this->vertices_VBO_id != 0);
|
||||
assert(this->triangle_indices_VBO_ids[triangle_indices_idx] != 0);
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
|
||||
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
// Render using the Vertex Buffer Objects.
|
||||
if (this->triangle_indices_sizes[triangle_indices_idx] > 0) {
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_ids[triangle_indices_idx]));
|
||||
glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_sizes[triangle_indices_idx]), 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(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
this->vertices.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void GLMmSegmentationGizmo3DScene::finalize_triangle_indices()
|
||||
{
|
||||
assert(triangle_indices_idx < this->triangle_indices.size());
|
||||
assert(std::all_of(triangle_indices_VBO_ids.cbegin(), triangle_indices_VBO_ids.cend(), [](const auto &ti_VBO_id) { return ti_VBO_id == 0; }));
|
||||
|
||||
assert(this->triangle_indices.size() == this->triangle_indices_VBO_ids.size());
|
||||
for (size_t buffer_idx = 0; buffer_idx < this->triangle_indices.size(); ++buffer_idx)
|
||||
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(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
this->triangle_indices[buffer_idx].clear();
|
||||
}
|
||||
}
|
||||
|
||||
void GLMmSegmentationGizmo3DScene::finalize_geometry()
|
||||
{
|
||||
assert(this->vertices_VBO_id == 0);
|
||||
assert(this->triangle_indices.size() == this->triangle_indices_VBO_ids.size());
|
||||
finalize_vertices();
|
||||
finalize_triangle_indices();
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
|||
|
|
@ -5,24 +5,80 @@
|
|||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
class TriangleSelectorMmuGui : public TriangleSelectorGUI {
|
||||
class GLMmSegmentationGizmo3DScene
|
||||
{
|
||||
public:
|
||||
explicit TriangleSelectorMmuGui(const TriangleMesh& mesh, const std::vector<std::array<float, 4>> &colors, const std::array<float, 4> &default_volume_color)
|
||||
: TriangleSelectorGUI(mesh), m_colors(colors), m_default_volume_color(default_volume_color) {
|
||||
// Plus 1 is because the first position is allocated for non-painted triangles.
|
||||
m_iva_colors = std::vector<GLIndexedVertexArray>(colors.size() + 1);
|
||||
GLMmSegmentationGizmo3DScene() = delete;
|
||||
|
||||
explicit GLMmSegmentationGizmo3DScene(size_t triangle_indices_buffers_count)
|
||||
{
|
||||
this->triangle_indices = std::vector<std::vector<int>>(triangle_indices_buffers_count);
|
||||
this->triangle_indices_sizes = std::vector<size_t>(triangle_indices_buffers_count);
|
||||
this->triangle_indices_VBO_ids = std::vector<unsigned int>(triangle_indices_buffers_count);
|
||||
}
|
||||
~TriangleSelectorMmuGui() override = default;
|
||||
|
||||
virtual ~GLMmSegmentationGizmo3DScene() { release_geometry(); }
|
||||
|
||||
[[nodiscard]] inline bool has_VBOs(size_t triangle_indices_idx) const
|
||||
{
|
||||
assert(triangle_indices_idx < this->triangle_indices.size());
|
||||
return this->triangle_indices_VBO_ids[triangle_indices_idx] != 0;
|
||||
}
|
||||
|
||||
// Finalize the initialization of the geometry and indices, upload the geometry and indices to OpenGL VBO objects
|
||||
// and possibly releasing it if it has been loaded into the VBOs.
|
||||
void finalize_geometry();
|
||||
// Release the geometry data, release OpenGL VBOs.
|
||||
void release_geometry();
|
||||
// Finalize the initialization of the geometry, upload the geometry to OpenGL VBO objects
|
||||
// and possibly releasing it if it has been loaded into the VBOs.
|
||||
void finalize_vertices();
|
||||
// Finalize the initialization of the indices, upload the indices to OpenGL VBO objects
|
||||
// and possibly releasing it if it has been loaded into the VBOs.
|
||||
void finalize_triangle_indices();
|
||||
|
||||
void clear()
|
||||
{
|
||||
this->vertices.clear();
|
||||
for (std::vector<int> &ti : this->triangle_indices)
|
||||
ti.clear();
|
||||
|
||||
for (size_t &triangle_indices_size : this->triangle_indices_sizes)
|
||||
triangle_indices_size = 0;
|
||||
}
|
||||
|
||||
void render(size_t triangle_indices_idx) const;
|
||||
|
||||
std::vector<float> vertices;
|
||||
std::vector<std::vector<int>> triangle_indices;
|
||||
|
||||
// When the triangle indices are loaded into the graphics card as Vertex Buffer Objects,
|
||||
// the above mentioned std::vectors are cleared and the following variables keep their original length.
|
||||
std::vector<size_t> triangle_indices_sizes;
|
||||
|
||||
// IDs of the Vertex Array Objects, into which the geometry has been loaded.
|
||||
// Zero if the VBOs are not sent to GPU yet.
|
||||
unsigned int vertices_VBO_id{0};
|
||||
std::vector<unsigned int> triangle_indices_VBO_ids;
|
||||
};
|
||||
|
||||
class TriangleSelectorMmGui : public TriangleSelectorGUI {
|
||||
public:
|
||||
// Plus 2 in the initialization of m_gizmo_scene is because the first position is allocated for non-painted triangles, and the last position is allocated for seed fill.
|
||||
explicit TriangleSelectorMmGui(const TriangleMesh &mesh, const std::vector<std::array<float, 4>> &colors, const std::array<float, 4> &default_volume_color)
|
||||
: TriangleSelectorGUI(mesh), m_colors(colors), m_default_volume_color(default_volume_color), m_gizmo_scene(colors.size() + 2) {}
|
||||
~TriangleSelectorMmGui() override = default;
|
||||
|
||||
// Render current selection. Transformation matrices are supposed
|
||||
// to be already set.
|
||||
void render(ImGuiWrapper* imgui) override;
|
||||
|
||||
private:
|
||||
void update_render_data();
|
||||
|
||||
const std::vector<std::array<float, 4>> &m_colors;
|
||||
std::vector<GLIndexedVertexArray> m_iva_colors;
|
||||
const std::array<float, 4> m_default_volume_color;
|
||||
GLIndexedVertexArray m_iva_seed_fill;
|
||||
GLMmSegmentationGizmo3DScene m_gizmo_scene;
|
||||
};
|
||||
|
||||
class GLGizmoMmuSegmentation : public GLGizmoPainterBase
|
||||
|
|
|
|||
|
|
@ -402,6 +402,8 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
} else
|
||||
m_triangle_selectors[m_rr.mesh_id]->select_patch(m_rr.hit, int(m_rr.facet), camera_pos, m_cursor_radius, m_cursor_type,
|
||||
new_state, trafo_matrix, m_triangle_splitting_enabled);
|
||||
|
||||
m_triangle_selectors[m_rr.mesh_id]->request_update_render_data();
|
||||
m_last_mouse_click = mouse_position;
|
||||
}
|
||||
|
||||
|
|
@ -428,8 +430,10 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
update_raycast_cache(mouse_position, camera, trafo_matrices);
|
||||
|
||||
auto seed_fill_unselect_all = [this]() {
|
||||
for (auto &triangle_selector : m_triangle_selectors)
|
||||
for (auto &triangle_selector : m_triangle_selectors) {
|
||||
triangle_selector->seed_fill_unselect_all_triangles();
|
||||
triangle_selector->request_update_render_data();
|
||||
}
|
||||
};
|
||||
|
||||
if (m_rr.mesh_id == -1) {
|
||||
|
|
@ -447,6 +451,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
|
||||
assert(m_rr.mesh_id < int(m_triangle_selectors.size()));
|
||||
m_triangle_selectors[m_rr.mesh_id]->seed_fill_select_triangles(m_rr.hit, int(m_rr.facet), m_seed_fill_angle);
|
||||
m_triangle_selectors[m_rr.mesh_id]->request_update_render_data();
|
||||
m_seed_fill_last_mesh_id = m_rr.mesh_id;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -589,28 +594,11 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
|
|||
static constexpr std::array<float, 4> enforcers_color{0.47f, 0.47f, 1.f, 1.f};
|
||||
static constexpr std::array<float, 4> blockers_color{1.f, 0.44f, 0.44f, 1.f};
|
||||
|
||||
int enf_cnt = 0;
|
||||
int blc_cnt = 0;
|
||||
|
||||
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
|
||||
iva->release_geometry();
|
||||
|
||||
for (const Triangle& tr : m_triangles) {
|
||||
if (!tr.valid() || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE)
|
||||
continue;
|
||||
|
||||
GLIndexedVertexArray &iva = tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers : m_iva_blockers;
|
||||
int & cnt = tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt : blc_cnt;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
iva.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal);
|
||||
iva.push_triangle(cnt, cnt + 1, cnt + 2);
|
||||
cnt += 3;
|
||||
if (m_update_render_data) {
|
||||
update_render_data();
|
||||
m_update_render_data = false;
|
||||
}
|
||||
|
||||
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
|
||||
iva->finalize_geometry(true);
|
||||
|
||||
auto* shader = wxGetApp().get_current_shader();
|
||||
if (! shader)
|
||||
return;
|
||||
|
|
@ -635,6 +623,33 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
|
|||
|
||||
|
||||
|
||||
void TriangleSelectorGUI::update_render_data()
|
||||
{
|
||||
int enf_cnt = 0;
|
||||
int blc_cnt = 0;
|
||||
|
||||
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
|
||||
iva->release_geometry();
|
||||
|
||||
for (const Triangle &tr : m_triangles) {
|
||||
if (!tr.valid() || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE)
|
||||
continue;
|
||||
|
||||
GLIndexedVertexArray &iva = tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers : m_iva_blockers;
|
||||
int & cnt = tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt : blc_cnt;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
iva.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal);
|
||||
iva.push_triangle(cnt, cnt + 1, cnt + 2);
|
||||
cnt += 3;
|
||||
}
|
||||
|
||||
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
|
||||
iva->finalize_geometry(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
|
||||
void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
|
||||
{
|
||||
|
|
@ -685,7 +700,7 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
|
|||
va = &m_varrays[ORIGINAL];
|
||||
cnt = &cnts[ORIGINAL];
|
||||
}
|
||||
else if (tr.valid) {
|
||||
else if (tr.valid()) {
|
||||
va = &m_varrays[SPLIT];
|
||||
cnt = &cnts[SPLIT];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,13 +38,20 @@ public:
|
|||
virtual void render(ImGuiWrapper *imgui);
|
||||
void render() { this->render(nullptr); }
|
||||
|
||||
void request_update_render_data() { m_update_render_data = true; };
|
||||
|
||||
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
|
||||
void render_debug(ImGuiWrapper* imgui);
|
||||
bool m_show_triangles{false};
|
||||
bool m_show_invalid{false};
|
||||
#endif
|
||||
|
||||
protected:
|
||||
bool m_update_render_data = false;
|
||||
|
||||
private:
|
||||
void update_render_data();
|
||||
|
||||
GLIndexedVertexArray m_iva_enforcers;
|
||||
GLIndexedVertexArray m_iva_blockers;
|
||||
std::array<GLIndexedVertexArray, 3> m_varrays;
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||
if (mv->is_model_part()) {
|
||||
++idx;
|
||||
m_triangle_selectors[idx]->reset();
|
||||
m_triangle_selectors[idx]->request_update_render_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,6 +258,7 @@ void GLGizmoSeam::update_from_model_object()
|
|||
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorGUI>(*mesh));
|
||||
m_triangle_selectors.back()->deserialize(mv->seam_facets.get_data());
|
||||
m_triangle_selectors.back()->request_update_render_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue