Simplify gizmo now renders the volume by itself,
it does not rely on the usual GLVolume rendering. GLCanvas3D::toggle_model_object_visibility was extended to hide a single volume. Rendering the model and wireframe uses the same vertex buffer, which is now used through GLModel class. GLGizmoRenderTransparent class should no longer be needed. GLCanvas3D::reload_scene calls replaced with request_rerender.
This commit is contained in:
parent
50ea144b84
commit
ba56a79795
@ -24,6 +24,7 @@
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
@ -1143,7 +1144,7 @@ void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObje
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject* mo, int instance_idx)
|
||||
void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject* mo, int instance_idx, const ModelVolume* mv)
|
||||
{
|
||||
for (GLVolume* vol : m_volumes.volumes) {
|
||||
if (vol->composite_id.object_id == 1000) { // wipe tower
|
||||
@ -1151,7 +1152,8 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject
|
||||
}
|
||||
else {
|
||||
if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo)
|
||||
&& (instance_idx == -1 || vol->composite_id.instance_id == instance_idx)) {
|
||||
&& (instance_idx == -1 || vol->composite_id.instance_id == instance_idx)
|
||||
&& (mv == nullptr || m_model->objects[vol->composite_id.object_id]->volumes[vol->composite_id.volume_id] == mv)) {
|
||||
vol->is_active = visible;
|
||||
|
||||
if (instance_idx == -1) {
|
||||
@ -5239,10 +5241,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
|
||||
{
|
||||
const GLGizmosManager& gm = get_gizmos_manager();
|
||||
GLGizmosManager::EType type = gm.get_current_type();
|
||||
if (type == GLGizmosManager::FdmSupports
|
||||
|| type == GLGizmosManager::Seam
|
||||
|| type == GLGizmosManager::MmuSegmentation
|
||||
|| type == GLGizmosManager::Simplify ) {
|
||||
if (dynamic_cast<GLGizmoPainterBase*>(gm.get_current())) {
|
||||
shader->stop_using();
|
||||
gm.render_painter_gizmo();
|
||||
shader->start_using();
|
||||
|
@ -635,7 +635,7 @@ public:
|
||||
void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); }
|
||||
|
||||
void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
|
||||
void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
|
||||
void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1, const ModelVolume* mv = nullptr);
|
||||
void update_instance_printable_state_for_object(size_t obj_idx);
|
||||
void update_instance_printable_state_for_objects(const std::vector<size_t>& object_idxs);
|
||||
|
||||
|
@ -99,20 +99,11 @@ protected:
|
||||
GLPaintContour m_paint_contour;
|
||||
};
|
||||
|
||||
class GLGizmoTransparentRender
|
||||
{
|
||||
public:
|
||||
// Following function renders the triangles and cursor. Having this separated
|
||||
// from usual on_render method allows to render them before transparent
|
||||
// objects, so they can be seen inside them. The usual on_render is called
|
||||
// after all volumes (including transparent ones) are rendered.
|
||||
virtual void render_painter_gizmo() const = 0;
|
||||
};
|
||||
|
||||
// Following class is a base class for a gizmo with ability to paint on mesh
|
||||
// using circular blush (such as FDM supports gizmo and seam painting gizmo).
|
||||
// The purpose is not to duplicate code related to mesh painting.
|
||||
class GLGizmoPainterBase : public GLGizmoTransparentRender, public GLGizmoBase
|
||||
class GLGizmoPainterBase : public GLGizmoBase
|
||||
{
|
||||
private:
|
||||
ObjectID m_old_mo_id;
|
||||
@ -125,6 +116,12 @@ public:
|
||||
virtual void set_painter_gizmo_data(const Selection& selection);
|
||||
virtual bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||
|
||||
// Following function renders the triangles and cursor. Having this separated
|
||||
// from usual on_render method allows to render them before transparent
|
||||
// objects, so they can be seen inside them. The usual on_render is called
|
||||
// after all volumes (including transparent ones) are rendered.
|
||||
virtual void render_painter_gizmo() const = 0;
|
||||
|
||||
protected:
|
||||
virtual void render_triangles(const Selection& selection) const;
|
||||
void render_cursor() const;
|
||||
|
@ -31,16 +31,12 @@ GLGizmoSimplify::GLGizmoSimplify(GLCanvas3D & parent,
|
||||
, tr_preview(_u8L("Preview"))
|
||||
, tr_detail_level(_u8L("Detail level"))
|
||||
, tr_decimate_ratio(_u8L("Decimate ratio"))
|
||||
// for wireframe
|
||||
, m_wireframe_VBO_id(0)
|
||||
, m_wireframe_IBO_id(0)
|
||||
, m_wireframe_IBO_size(0)
|
||||
{}
|
||||
|
||||
GLGizmoSimplify::~GLGizmoSimplify() {
|
||||
m_state = State::canceling;
|
||||
if (m_worker.joinable()) m_worker.join();
|
||||
free_gpu();
|
||||
m_glmodel.reset();
|
||||
}
|
||||
|
||||
bool GLGizmoSimplify::on_esc_key_down() {
|
||||
@ -143,7 +139,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
||||
m_configuration.fix_count_by_ratio(m_volume->mesh().its.indices.size());
|
||||
m_is_valid_result = false;
|
||||
m_exist_preview = false;
|
||||
init_wireframe();
|
||||
init_model();
|
||||
live_preview();
|
||||
|
||||
// set window position
|
||||
@ -266,10 +262,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
||||
ImGui::Text(_u8L("%d triangles").c_str(), m_configuration.wanted_count);
|
||||
m_imgui->disabled_end(); // use_count
|
||||
|
||||
if (ImGui::Checkbox(_u8L("Show wireframe").c_str(), &m_show_wireframe)) {
|
||||
if (m_show_wireframe) init_wireframe();
|
||||
else free_gpu();
|
||||
}
|
||||
ImGui::Checkbox(_u8L("Show wireframe").c_str(), &m_show_wireframe);
|
||||
|
||||
bool is_canceling = m_state == State::canceling;
|
||||
m_imgui->disabled_begin(is_canceling);
|
||||
@ -322,11 +315,11 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
||||
m_need_reload = false;
|
||||
bool close_on_end = (m_state == State::close_on_end);
|
||||
// Reload visualization of mesh - change VBO, FBO on GPU
|
||||
m_parent.reload_scene(true);
|
||||
request_rerender();
|
||||
// set m_state must be before close() !!!
|
||||
m_state = State::settings;
|
||||
if (close_on_end) after_apply();
|
||||
else init_wireframe();
|
||||
else init_model();
|
||||
// Fix warning icon in object list
|
||||
wxGetApp().obj_list()->update_item_error_icon(m_obj_index, -1);
|
||||
}
|
||||
@ -469,6 +462,8 @@ void GLGizmoSimplify::on_set_state()
|
||||
{
|
||||
// Closing gizmo. e.g. selecting another one
|
||||
if (GLGizmoBase::m_state == GLGizmoBase::Off) {
|
||||
m_parent.toggle_model_objects_visibility(true);
|
||||
|
||||
// can appear when delete objects
|
||||
bool empty_selection = m_parent.get_selection().is_empty();
|
||||
|
||||
@ -495,7 +490,7 @@ void GLGizmoSimplify::on_set_state()
|
||||
m_exist_preview = false;
|
||||
if (exist_volume(m_volume)) {
|
||||
set_its(*m_original_its);
|
||||
m_parent.reload_scene(false);
|
||||
request_rerender();
|
||||
m_need_reload = false;
|
||||
}
|
||||
}
|
||||
@ -581,44 +576,25 @@ const ModelVolume *GLGizmoSimplify::get_volume(const GLVolume::CompositeID &cid,
|
||||
return obj->volumes[cid.volume_id];
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::init_wireframe()
|
||||
void GLGizmoSimplify::init_model()
|
||||
{
|
||||
if (!m_show_wireframe) return;
|
||||
const indexed_triangle_set &its = m_volume->mesh().its;
|
||||
free_gpu();
|
||||
if (its.indices.empty()) return;
|
||||
|
||||
// vertices
|
||||
glsafe(::glGenBuffers(1, &m_wireframe_VBO_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_wireframe_VBO_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER,
|
||||
its.vertices.size() * 3 * sizeof(float),
|
||||
its.vertices.data(), GL_STATIC_DRAW));
|
||||
m_glmodel.reset();
|
||||
m_glmodel.init_from(its);
|
||||
m_parent.toggle_model_objects_visibility(false, m_c->selection_info()->model_object(),
|
||||
m_c->selection_info()->get_active_instance(), m_volume);
|
||||
|
||||
// indices
|
||||
std::vector<Vec2i> contour_indices;
|
||||
contour_indices.reserve((its.indices.size() * 3) / 2);
|
||||
for (const auto &triangle : its.indices) {
|
||||
for (size_t ti1 = 0; ti1 < 3; ++ti1) {
|
||||
size_t ti2 = (ti1 == 2) ? 0 : (ti1 + 1);
|
||||
if (triangle[ti1] > triangle[ti2]) continue;
|
||||
contour_indices.emplace_back(triangle[ti1], triangle[ti2]);
|
||||
}
|
||||
}
|
||||
glsafe(::glGenBuffers(1, &m_wireframe_IBO_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_wireframe_IBO_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER,
|
||||
2*contour_indices.size() * sizeof(coord_t),
|
||||
contour_indices.data(), GL_STATIC_DRAW));
|
||||
m_wireframe_IBO_size = contour_indices.size() * 2;
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
if (const Selection&sel = m_parent.get_selection(); sel.get_volume_idxs().size() == 1)
|
||||
m_glmodel.set_color(-1, sel.get_volume(*sel.get_volume_idxs().begin())->color);
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::render_wireframe() const
|
||||
void GLGizmoSimplify::on_render()
|
||||
{
|
||||
// is initialized?
|
||||
if (m_wireframe_VBO_id == 0 || m_wireframe_IBO_id == 0) return;
|
||||
if (!m_show_wireframe) return;
|
||||
if (! m_glmodel.is_initialized())
|
||||
return;
|
||||
|
||||
const auto& selection = m_parent.get_selection();
|
||||
const auto& volume_idxs = selection.get_volume_idxs();
|
||||
@ -633,39 +609,35 @@ void GLGizmoSimplify::render_wireframe() const
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixd(trafo_matrix.data()));
|
||||
|
||||
auto *contour_shader = wxGetApp().get_shader("mm_contour");
|
||||
contour_shader->start_using();
|
||||
glsafe(::glDepthFunc(GL_LEQUAL));
|
||||
glsafe(::glLineWidth(1.0f));
|
||||
auto *gouraud_shader = wxGetApp().get_shader("gouraud_light");
|
||||
glsafe(::glPushAttrib(GL_DEPTH_TEST));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
gouraud_shader->start_using();
|
||||
m_glmodel.render();
|
||||
gouraud_shader->stop_using();
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_wireframe_VBO_id));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), nullptr));
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
if (m_show_wireframe) {
|
||||
auto* contour_shader = wxGetApp().get_shader("mm_contour");
|
||||
contour_shader->start_using();
|
||||
glsafe(::glLineWidth(1.0f));
|
||||
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
|
||||
//ScopeGuard offset_fill_guard([]() { glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); });
|
||||
//glsafe(::glEnable(GL_POLYGON_OFFSET_FILL));
|
||||
//glsafe(::glPolygonOffset(5.0, 5.0));
|
||||
m_glmodel.render();
|
||||
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
|
||||
contour_shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_wireframe_IBO_id));
|
||||
glsafe(::glDrawElements(GL_LINES, m_wireframe_IBO_size, GL_UNSIGNED_INT, nullptr));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
glsafe(::glDepthFunc(GL_LESS));
|
||||
|
||||
glsafe(::glPopMatrix()); // pop trafo
|
||||
contour_shader->stop_using();
|
||||
glsafe(::glPopAttrib());
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::free_gpu()
|
||||
{
|
||||
if (m_wireframe_VBO_id != 0) {
|
||||
glsafe(::glDeleteBuffers(1, &m_wireframe_VBO_id));
|
||||
m_wireframe_VBO_id = 0;
|
||||
}
|
||||
|
||||
if (m_wireframe_IBO_id != 0) {
|
||||
glsafe(::glDeleteBuffers(1, &m_wireframe_IBO_id));
|
||||
m_wireframe_IBO_id = 0;
|
||||
}
|
||||
CommonGizmosDataID GLGizmoSimplify::on_get_requirements() const
|
||||
{
|
||||
return CommonGizmosDataID(
|
||||
int(CommonGizmosDataID::SelectionInfo));
|
||||
}
|
||||
|
||||
} // namespace Slic3r::GUI
|
||||
|
@ -4,6 +4,7 @@
|
||||
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code,
|
||||
// which overrides our localization "L" macro.
|
||||
#include "GLGizmoBase.hpp"
|
||||
#include "slic3r/GUI/GLModel.hpp"
|
||||
#include "GLGizmoPainterBase.hpp" // for render wireframe
|
||||
#include "admesh/stl.h" // indexed_triangle_set
|
||||
#include <thread>
|
||||
@ -24,7 +25,7 @@ class ModelVolume;
|
||||
namespace GUI {
|
||||
class NotificationManager; // for simplify suggestion
|
||||
|
||||
class GLGizmoSimplify: public GLGizmoBase, public GLGizmoTransparentRender // GLGizmoBase
|
||||
class GLGizmoSimplify: public GLGizmoBase
|
||||
{
|
||||
public:
|
||||
GLGizmoSimplify(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
@ -43,11 +44,10 @@ protected:
|
||||
|
||||
// must implement
|
||||
virtual bool on_init() override { return true;};
|
||||
virtual void on_render() override{};
|
||||
virtual void on_render() override;
|
||||
virtual void on_render_for_picking() override{};
|
||||
|
||||
// GLGizmoPainterBase
|
||||
virtual void render_painter_gizmo() const override{ render_wireframe(); }
|
||||
virtual CommonGizmosDataID on_get_requirements() const;
|
||||
private:
|
||||
void after_apply();
|
||||
void close();
|
||||
@ -75,7 +75,8 @@ private:
|
||||
size_t m_obj_index;
|
||||
|
||||
std::optional<indexed_triangle_set> m_original_its;
|
||||
bool m_show_wireframe;
|
||||
bool m_show_wireframe;
|
||||
GLModel m_glmodel;
|
||||
|
||||
std::atomic<bool> m_need_reload; // after simplify, glReload must be on main thread
|
||||
|
||||
@ -142,12 +143,7 @@ private:
|
||||
const std::string tr_detail_level;
|
||||
const std::string tr_decimate_ratio;
|
||||
|
||||
// rendering wireframe
|
||||
void render_wireframe() const;
|
||||
void init_wireframe();
|
||||
void free_gpu();
|
||||
GLuint m_wireframe_VBO_id, m_wireframe_IBO_id;
|
||||
size_t m_wireframe_IBO_size;
|
||||
void init_model();
|
||||
|
||||
// cancel exception
|
||||
class SimplifyCanceledException: public std::exception
|
||||
|
@ -483,7 +483,7 @@ void GLGizmosManager::render_painter_gizmo() const
|
||||
if (!m_enabled || m_current == Undefined)
|
||||
return;
|
||||
|
||||
auto *gizmo = dynamic_cast<GLGizmoTransparentRender*>(get_current());
|
||||
auto *gizmo = dynamic_cast<GLGizmoPainterBase*>(get_current());
|
||||
assert(gizmo); // check the precondition
|
||||
gizmo->render_painter_gizmo();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user