mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-26 18:21:18 -06:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_sinking_objects_collision
This commit is contained in:
commit
1f82eb5624
25 changed files with 477 additions and 500 deletions
|
|
@ -136,6 +136,7 @@ public:
|
|||
bool is_selectable() const { return on_is_selectable(); }
|
||||
CommonGizmosDataID get_requirements() const { return on_get_requirements(); }
|
||||
virtual bool wants_enter_leave_snapshots() const { return false; }
|
||||
virtual std::string get_action_snapshot_name() { return _u8L("Gizmo action"); }
|
||||
void set_common_data_pool(CommonGizmosDataPool* ptr) { m_c = ptr; }
|
||||
|
||||
unsigned int get_sprite_id() const { return m_sprite_id; }
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
|
@ -165,7 +166,8 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
ImGui::Separator();
|
||||
|
||||
if (m_imgui->button(m_desc.at("remove_all"))) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), wxString(_L("Reset selection")));
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Reset selection"),
|
||||
UndoRedo::SnapshotType::GizmoAction);
|
||||
ModelObject* mo = m_c->selection_info()->model_object();
|
||||
int idx = -1;
|
||||
for (ModelVolume* mv : mo->volumes) {
|
||||
|
|
@ -298,8 +300,6 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block)
|
|||
}
|
||||
}
|
||||
|
||||
activate_internal_undo_redo_stack(true);
|
||||
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), block ? _L("Block supports by angle")
|
||||
: _L("Add supports by angle"));
|
||||
update_model_object();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ protected:
|
|||
|
||||
std::string get_gizmo_entering_text() const override { return _u8L("Entering Paint-on supports"); }
|
||||
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Paint-on supports"); }
|
||||
std::string get_action_snapshot_name() override { return _u8L("Paint-on supports editing"); }
|
||||
|
||||
|
||||
private:
|
||||
bool on_init() override;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "slic3r/GUI/NotificationManager.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
|
@ -503,7 +504,8 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||
|
||||
ImGui::Separator();
|
||||
if (m_imgui->button(m_desc.at("remove_all"))) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), wxString(_L("Reset selection")));
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Reset selection"),
|
||||
UndoRedo::SnapshotType::GizmoAction);
|
||||
ModelObject * mo = m_c->selection_info()->model_object();
|
||||
int idx = -1;
|
||||
for (ModelVolume *mv : mo->volumes)
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ protected:
|
|||
|
||||
std::string get_gizmo_entering_text() const override { return _u8L("Entering Multimaterial painting"); }
|
||||
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Multimaterial painting"); }
|
||||
std::string get_action_snapshot_name() override { return _u8L("Multimaterial painting editing"); }
|
||||
|
||||
size_t m_first_selected_extruder_idx = 0;
|
||||
size_t m_second_selected_extruder_idx = 1;
|
||||
|
|
|
|||
|
|
@ -26,35 +26,6 @@ GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& ic
|
|||
m_vbo_sphere.finalize_geometry(true);
|
||||
}
|
||||
|
||||
// port of 948bc382655993721d93d3b9fce9b0186fcfb211
|
||||
void GLGizmoPainterBase::activate_internal_undo_redo_stack(bool activate)
|
||||
{
|
||||
Plater* plater = wxGetApp().plater();
|
||||
|
||||
// Following is needed to prevent taking an extra snapshot when the activation of
|
||||
// the internal stack happens when the gizmo is already active (such as open gizmo,
|
||||
// close gizmo, undo, start painting). The internal stack does not activate on the
|
||||
// undo, because that would obliterate all future of the main stack (user would
|
||||
// have to close the gizmo himself, he has no access to main undo/redo after the
|
||||
// internal stack opens). We don't want the "entering" snapshot taken in this case,
|
||||
// because there already is one.
|
||||
std::string last_snapshot_name;
|
||||
plater->undo_redo_topmost_string_getter(plater->can_undo(), last_snapshot_name);
|
||||
|
||||
if (activate && !m_internal_stack_active) {
|
||||
if (std::string str = this->get_gizmo_entering_text(); last_snapshot_name != str)
|
||||
Plater::TakeSnapshot(plater, str, UndoRedo::SnapshotType::EnteringGizmo);
|
||||
plater->enter_gizmos_stack();
|
||||
m_internal_stack_active = true;
|
||||
}
|
||||
if (!activate && m_internal_stack_active) {
|
||||
plater->leave_gizmos_stack();
|
||||
if (std::string str = this->get_gizmo_leaving_text(); last_snapshot_name != str)
|
||||
Plater::TakeSnapshot(plater, str, UndoRedo::SnapshotType::LeavingGizmoWithAction);
|
||||
m_internal_stack_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoPainterBase::set_painter_gizmo_data(const Selection& selection)
|
||||
{
|
||||
if (m_state != On)
|
||||
|
|
@ -462,8 +433,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
&& m_button_down != Button::None) {
|
||||
// Take snapshot and update ModelVolume data.
|
||||
wxString action_name = this->handle_snapshot_action_name(shift_down, m_button_down);
|
||||
activate_internal_undo_redo_stack(true);
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), action_name);
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), action_name, UndoRedo::SnapshotType::GizmoAction);
|
||||
update_model_object();
|
||||
|
||||
m_button_down = Button::None;
|
||||
|
|
@ -560,16 +530,10 @@ void GLGizmoPainterBase::on_set_state()
|
|||
|
||||
if (m_state == On && m_old_state != On) { // the gizmo was just turned on
|
||||
on_opening();
|
||||
if (! m_parent.get_gizmos_manager().is_serializing()) {
|
||||
wxGetApp().CallAfter([this]() {
|
||||
activate_internal_undo_redo_stack(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
|
||||
// we are actually shutting down
|
||||
on_shutdown();
|
||||
activate_internal_undo_redo_stack(false);
|
||||
m_old_mo_id = -1;
|
||||
//m_iva.release_geometry();
|
||||
m_triangle_selectors.clear();
|
||||
|
|
|
|||
|
|
@ -57,30 +57,32 @@ private:
|
|||
std::array<GLIndexedVertexArray, 3> m_varrays;
|
||||
};
|
||||
|
||||
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 GLGizmoBase
|
||||
class GLGizmoPainterBase : public GLGizmoTransparentRender, public GLGizmoBase
|
||||
{
|
||||
private:
|
||||
ObjectID m_old_mo_id;
|
||||
size_t m_old_volumes_size = 0;
|
||||
void on_render() override {}
|
||||
void on_render_for_picking() override {}
|
||||
|
||||
public:
|
||||
GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
~GLGizmoPainterBase() override = default;
|
||||
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:
|
||||
void render_triangles(const Selection& selection, const bool use_polygon_offset_fill = true) const;
|
||||
void render_cursor() const;
|
||||
|
|
@ -88,7 +90,6 @@ protected:
|
|||
void render_cursor_sphere(const Transform3d& trafo) const;
|
||||
virtual void update_model_object() const = 0;
|
||||
virtual void update_from_model_object() = 0;
|
||||
void activate_internal_undo_redo_stack(bool activate);
|
||||
|
||||
virtual std::array<float, 4> get_cursor_sphere_left_button_color() const { return {0.f, 0.f, 1.f, 0.25f}; }
|
||||
virtual std::array<float, 4> get_cursor_sphere_right_button_color() const { return {1.f, 0.f, 0.f, 0.25f}; }
|
||||
|
|
@ -170,6 +171,7 @@ protected:
|
|||
void on_load(cereal::BinaryInputArchive& ar) override;
|
||||
void on_save(cereal::BinaryOutputArchive& ar) const override {}
|
||||
CommonGizmosDataID on_get_requirements() const override;
|
||||
bool wants_enter_leave_snapshots() const override { return true; }
|
||||
|
||||
virtual wxString handle_snapshot_action_name(bool shift_down, Button button_down) const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
|
|
@ -121,7 +122,8 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||
m_imgui->text("");
|
||||
|
||||
if (m_imgui->button(m_desc.at("remove_all"))) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), wxString(_L("Reset selection")));
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Reset selection"),
|
||||
UndoRedo::SnapshotType::GizmoAction);
|
||||
ModelObject* mo = m_c->selection_info()->model_object();
|
||||
int idx = -1;
|
||||
for (ModelVolume* mv : mo->volumes) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ protected:
|
|||
|
||||
std::string get_gizmo_entering_text() const override { return _u8L("Entering Seam painting"); }
|
||||
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Seam painting"); }
|
||||
std::string get_action_snapshot_name() override { return _u8L("Paint-on seam editing"); }
|
||||
|
||||
private:
|
||||
bool on_init() override;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "GLGizmoSimplify.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
||||
|
|
@ -21,18 +22,23 @@ GLGizmoSimplify::GLGizmoSimplify(GLCanvas3D & parent,
|
|||
, m_progress(0)
|
||||
, m_volume(nullptr)
|
||||
, m_obj_index(0)
|
||||
, m_need_reload(false)
|
||||
, m_need_reload(false)
|
||||
, m_show_wireframe(false)
|
||||
|
||||
, tr_mesh_name(_u8L("Mesh name"))
|
||||
, tr_triangles(_u8L("Triangles"))
|
||||
, tr_preview(_u8L("Preview"))
|
||||
, tr_detail_level(_u8L("Detail level"))
|
||||
, tr_decimate_ratio(_u8L("Decimate ratio"))
|
||||
|
||||
, m_wireframe_VBO_id(0)
|
||||
, m_wireframe_IBO_id(0)
|
||||
{}
|
||||
|
||||
GLGizmoSimplify::~GLGizmoSimplify() {
|
||||
m_state = State::canceling;
|
||||
if (m_worker.joinable()) m_worker.join();
|
||||
free_gpu();
|
||||
}
|
||||
|
||||
bool GLGizmoSimplify::on_init()
|
||||
|
|
@ -47,7 +53,8 @@ std::string GLGizmoSimplify::on_get_name() const
|
|||
return _u8L("Simplify");
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::on_render() {}
|
||||
void GLGizmoSimplify::on_render() { }
|
||||
|
||||
void GLGizmoSimplify::on_render_for_picking() {}
|
||||
|
||||
void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limit)
|
||||
|
|
@ -55,8 +62,12 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
create_gui_cfg();
|
||||
int obj_index;
|
||||
ModelVolume *act_volume = get_selected_volume(&obj_index);
|
||||
if (act_volume == nullptr) {
|
||||
close();
|
||||
if (act_volume == nullptr) {
|
||||
switch (m_state) {
|
||||
case State::settings: close(); break;
|
||||
case State::canceling: break;
|
||||
default: m_state = State::canceling;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +87,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();
|
||||
|
||||
if (change_window_position) {
|
||||
ImVec2 pos = ImGui::GetMousePos();
|
||||
|
|
@ -98,7 +110,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
|
||||
int flag = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoCollapse;
|
||||
m_imgui->begin(get_name(), flag);
|
||||
m_imgui->begin(on_get_name(), flag);
|
||||
|
||||
size_t triangle_count = m_volume->mesh().its.indices.size();
|
||||
// already reduced mesh
|
||||
|
|
@ -189,6 +201,11 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
ImGui::Text(_L("%d triangles").c_str(), m_configuration.wanted_count);
|
||||
m_imgui->disabled_end(); // use_count
|
||||
|
||||
if (ImGui::Checkbox(_L("Show wireframe").c_str(), &m_show_wireframe)) {
|
||||
if (m_show_wireframe) init_wireframe();
|
||||
else free_gpu();
|
||||
}
|
||||
|
||||
if (m_state == State::settings) {
|
||||
if (m_imgui->button(_L("Cancel"))) {
|
||||
if (m_original_its.has_value()) {
|
||||
|
|
@ -237,7 +254,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
// set m_state must be before close() !!!
|
||||
m_state = State::settings;
|
||||
if (close_on_end) after_apply();
|
||||
|
||||
else init_wireframe();
|
||||
// Fix warning icon in object list
|
||||
wxGetApp().obj_list()->update_item_error_icon(m_obj_index, -1);
|
||||
}
|
||||
|
|
@ -330,10 +347,18 @@ void GLGizmoSimplify::on_set_state()
|
|||
{
|
||||
// Closing gizmo. e.g. selecting another one
|
||||
if (GLGizmoBase::m_state == GLGizmoBase::Off) {
|
||||
bool exist_selected_object = is_selected_object();
|
||||
// can appear when delete objects
|
||||
bool empty_selection = m_parent.get_selection().is_empty();
|
||||
|
||||
// cancel processing
|
||||
if (empty_selection &&
|
||||
m_state != State::settings &&
|
||||
m_state != State::canceling)
|
||||
m_state = State::canceling;
|
||||
|
||||
// refuse outgoing during simlification
|
||||
// object is not selected when it is deleted(cancel and close gizmo)
|
||||
if (m_state != State::settings && exist_selected_object) {
|
||||
if (m_state != State::settings && !empty_selection) {
|
||||
GLGizmoBase::m_state = GLGizmoBase::On;
|
||||
auto notification_manager = wxGetApp().plater()->get_notification_manager();
|
||||
notification_manager->push_notification(
|
||||
|
|
@ -344,10 +369,13 @@ void GLGizmoSimplify::on_set_state()
|
|||
}
|
||||
|
||||
// revert preview
|
||||
if (m_exist_preview && exist_selected_object) {
|
||||
set_its(*m_original_its);
|
||||
m_parent.reload_scene(true);
|
||||
m_need_reload = false;
|
||||
if (m_exist_preview) {
|
||||
m_exist_preview = false;
|
||||
if (exist_volume(m_volume)) {
|
||||
set_its(*m_original_its);
|
||||
m_parent.reload_scene(false);
|
||||
m_need_reload = false;
|
||||
}
|
||||
}
|
||||
|
||||
// invalidate selected model
|
||||
|
|
@ -385,33 +413,110 @@ void GLGizmoSimplify::request_rerender() {
|
|||
});
|
||||
}
|
||||
|
||||
bool GLGizmoSimplify::is_selected_object(int *object_idx)
|
||||
{
|
||||
int index = (object_idx != nullptr) ? *object_idx :
|
||||
m_parent.get_selection().get_object_idx();
|
||||
// no selected object --> can appear after delete model
|
||||
if (index < 0) {
|
||||
switch (m_state) {
|
||||
case State::settings: close(); break;
|
||||
case State::canceling: break;
|
||||
default: m_state = State::canceling;
|
||||
}
|
||||
return false;
|
||||
bool GLGizmoSimplify::exist_volume(ModelVolume *volume) {
|
||||
auto objs = wxGetApp().plater()->model().objects;
|
||||
for (const auto &obj : objs) {
|
||||
const auto &vlms = obj->volumes;
|
||||
auto item = std::find(vlms.begin(), vlms.end(), volume);
|
||||
if (item != vlms.end()) return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ModelVolume *GLGizmoSimplify::get_selected_volume(int *object_idx_ptr)
|
||||
ModelVolume *GLGizmoSimplify::get_selected_volume(int *object_idx_ptr) const
|
||||
{
|
||||
const Selection &selection = m_parent.get_selection();
|
||||
int object_idx = selection.get_object_idx();
|
||||
if (object_idx_ptr != nullptr) *object_idx_ptr = object_idx;
|
||||
if (!is_selected_object(&object_idx)) return nullptr;
|
||||
if (object_idx < 0) return nullptr;
|
||||
ModelObjectPtrs &objs = wxGetApp().plater()->model().objects;
|
||||
if (objs.size() <= object_idx) return nullptr;
|
||||
if (static_cast<int>(objs.size()) <= object_idx) return nullptr;
|
||||
ModelObject *obj = objs[object_idx];
|
||||
if (obj->volumes.empty()) return nullptr;
|
||||
return obj->volumes.front();
|
||||
return obj->volumes.front();
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::init_wireframe()
|
||||
{
|
||||
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));
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::render_wireframe() const
|
||||
{
|
||||
// is initialized?
|
||||
if (m_wireframe_VBO_id == 0 || m_wireframe_IBO_id == 0) return;
|
||||
if (!m_show_wireframe) return;
|
||||
ModelVolume *act_volume = get_selected_volume();
|
||||
if (act_volume == nullptr) return;
|
||||
const Transform3d trafo_matrix =
|
||||
act_volume->get_object()->instances[m_parent.get_selection().get_instance_idx()]
|
||||
->get_transformation().get_matrix() *
|
||||
act_volume->get_matrix();
|
||||
|
||||
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));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_wireframe_VBO_id));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), nullptr));
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r::GUI
|
||||
|
|
|
|||
|
|
@ -4,11 +4,14 @@
|
|||
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code,
|
||||
// which overrides our localization "L" macro.
|
||||
#include "GLGizmoBase.hpp"
|
||||
#include "GLGizmoPainterBase.hpp" // for render wireframe
|
||||
#include "admesh/stl.h" // indexed_triangle_set
|
||||
#include <thread>
|
||||
#include <optional>
|
||||
#include <atomic>
|
||||
|
||||
#include <GL/glew.h> // GLUint
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class ModelVolume;
|
||||
|
|
@ -16,7 +19,7 @@ class ModelVolume;
|
|||
namespace GUI {
|
||||
|
||||
|
||||
class GLGizmoSimplify : public GLGizmoBase
|
||||
class GLGizmoSimplify: public GLGizmoBase, public GLGizmoTransparentRender // GLGizmoBase
|
||||
{
|
||||
public:
|
||||
GLGizmoSimplify(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
|
|
@ -31,6 +34,8 @@ protected:
|
|||
virtual bool on_is_selectable() const override { return false; }
|
||||
virtual void on_set_state() override;
|
||||
|
||||
// GLGizmoPainterBase
|
||||
virtual void render_painter_gizmo() const override{ render_wireframe(); }
|
||||
private:
|
||||
void after_apply();
|
||||
void close();
|
||||
|
|
@ -38,8 +43,10 @@ private:
|
|||
void set_its(indexed_triangle_set &its);
|
||||
void create_gui_cfg();
|
||||
void request_rerender();
|
||||
bool is_selected_object(int *object_idx_ptr = nullptr);
|
||||
ModelVolume *get_selected_volume(int *object_idx = nullptr);
|
||||
ModelVolume *get_selected_volume(int *object_idx = nullptr) const;
|
||||
|
||||
// return false when volume was deleted
|
||||
static bool exist_volume(ModelVolume *volume);
|
||||
|
||||
std::atomic_bool m_is_valid_result; // differ what to do in apply
|
||||
std::atomic_bool m_exist_preview; // set when process end
|
||||
|
|
@ -49,6 +56,7 @@ private:
|
|||
size_t m_obj_index;
|
||||
|
||||
std::optional<indexed_triangle_set> m_original_its;
|
||||
bool m_show_wireframe;
|
||||
|
||||
volatile bool m_need_reload; // after simplify, glReload must be on main thread
|
||||
std::thread m_worker;
|
||||
|
|
@ -101,6 +109,13 @@ private:
|
|||
const std::string tr_preview;
|
||||
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;
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ std::vector<size_t> GLGizmosManager::get_selectable_idxs() const
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const
|
||||
{
|
||||
if (! m_enabled)
|
||||
|
|
@ -485,7 +483,7 @@ void GLGizmosManager::render_painter_gizmo() const
|
|||
if (!m_enabled || m_current == Undefined)
|
||||
return;
|
||||
|
||||
auto* gizmo = dynamic_cast<GLGizmoPainterBase*>(get_current());
|
||||
auto *gizmo = dynamic_cast<GLGizmoTransparentRender*>(get_current());
|
||||
assert(gizmo); // check the precondition
|
||||
gizmo->render_painter_gizmo();
|
||||
}
|
||||
|
|
@ -1222,13 +1220,15 @@ bool GLGizmosManager::activate_gizmo(EType type)
|
|||
if (! m_parent.get_gizmos_manager().is_serializing()
|
||||
&& old_gizmo->wants_enter_leave_snapshots())
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(),
|
||||
Slic3r::format(_utf8("Leaving %1%"), old_gizmo->get_name(false)));
|
||||
Slic3r::format(_utf8("Leaving %1%"), old_gizmo->get_name(false)),
|
||||
UndoRedo::SnapshotType::LeavingGizmoWithAction);
|
||||
}
|
||||
|
||||
if (new_gizmo && ! m_parent.get_gizmos_manager().is_serializing()
|
||||
&& new_gizmo->wants_enter_leave_snapshots())
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(),
|
||||
Slic3r::format(_utf8("Entering %1%"), new_gizmo->get_name(false)));
|
||||
Slic3r::format(_utf8("Entering %1%"), new_gizmo->get_name(false)),
|
||||
UndoRedo::SnapshotType::EnteringGizmo);
|
||||
|
||||
m_current = type;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue