Gizmos refactoring - Removed GLModels defined into GLGizmoBase, and mostly unused, to avoid wasting GPU memory. Use a shared GLModel for Gizmos inheriting from GLGizmoPainterBase. Initialization of GLModels moved from constructor to render methods

This commit is contained in:
enricoturri1966 2021-12-10 11:28:12 +01:00
parent d561d3579a
commit e3d5cd445c
12 changed files with 52 additions and 47 deletions

View File

@ -50,13 +50,12 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const
void GLGizmoBase::Grabber::render(float size, const std::array<float, 4>& render_color, bool picking) const
{
if (! cube_initialized) {
if (!cube.is_initialized()) {
// This cannot be done in constructor, OpenGL is not yet
// initialized at that point (on Linux at least).
indexed_triangle_set mesh = its_make_cube(1., 1., 1.);
its_translate(mesh, Vec3f(-0.5, -0.5, -0.5));
const_cast<GLModel&>(cube).init_from(mesh, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } });
const_cast<bool&>(cube_initialized) = true;
}
float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size));
@ -90,15 +89,11 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u
m_base_color = DEFAULT_BASE_COLOR;
m_drag_color = DEFAULT_DRAG_COLOR;
m_highlight_color = DEFAULT_HIGHLIGHT_COLOR;
m_cone.init_from(its_make_cone(1., 1., 2 * PI / 24));
m_sphere.init_from(its_make_sphere(1., (2 * M_PI) / 24.));
m_cylinder.init_from(its_make_cylinder(1., 1., 2 * PI / 24.));
}
void GLGizmoBase::set_hover_id(int id)
{
if (m_grabbers.empty() || (id < (int)m_grabbers.size()))
{
if (m_grabbers.empty() || id < (int)m_grabbers.size()) {
m_hover_id = id;
on_set_hover_id();
}

View File

@ -66,7 +66,6 @@ protected:
void render(float size, const std::array<float, 4>& render_color, bool picking) const;
GLModel cube;
bool cube_initialized = false;
};
public:
@ -105,9 +104,6 @@ protected:
bool m_first_input_window_render;
mutable std::string m_tooltip;
CommonGizmosDataPool* m_c;
GLModel m_cone;
GLModel m_cylinder;
GLModel m_sphere;
public:
GLGizmoBase(GLCanvas3D& parent,

View File

@ -20,7 +20,6 @@ namespace GUI {
GLGizmoHollow::GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
{
m_vbo_cylinder.init_from(its_make_cylinder(1., 1.));
}
@ -63,6 +62,9 @@ void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&)
void GLGizmoHollow::on_render()
{
if (!m_cylinder.is_initialized())
m_cylinder.init_from(its_make_cylinder(1.0, 1.0));
const Selection& selection = m_parent.get_selection();
const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info();
@ -148,11 +150,11 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
}
}
const_cast<GLModel*>(&m_vbo_cylinder)->set_color(-1, render_color);
const_cast<GLModel*>(&m_cylinder)->set_color(-1, render_color);
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
glsafe(::glPushMatrix());
glsafe(::glTranslatef(drain_hole.pos(0), drain_hole.pos(1), drain_hole.pos(2)));
glsafe(::glTranslatef(drain_hole.pos.x(), drain_hole.pos.y(), drain_hole.pos.z()));
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
if (vol->is_left_handed())
@ -166,7 +168,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
glsafe(::glPushMatrix());
glsafe(::glTranslated(0., 0., -drain_hole.height));
glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
m_vbo_cylinder.render();
m_cylinder.render();
glsafe(::glPopMatrix());
if (vol->is_left_handed())

View File

@ -48,7 +48,8 @@ private:
ObjectID m_old_mo_id = -1;
GLModel m_vbo_cylinder;
GLModel m_cylinder;
float m_new_hole_radius = 2.f; // Size of a new hole.
float m_new_hole_height = 6.f;
mutable std::vector<bool> m_selected; // which holes are currently selected

View File

@ -20,7 +20,6 @@ GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filenam
, m_starting_box_center(Vec3d::Zero())
, m_starting_box_bottom_center(Vec3d::Zero())
{
m_vbo_cone.init_from(its_make_cone(1., 1., 2*PI/36));
}
std::string GLGizmoMove3D::get_tooltip() const
@ -89,6 +88,9 @@ void GLGizmoMove3D::on_update(const UpdateData& data)
void GLGizmoMove3D::on_render()
{
if (!m_cone.is_initialized())
m_cone.init_from(its_make_cone(1.0, 1.0, double(PI) / 18.0));
const Selection& selection = m_parent.get_selection();
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
@ -205,7 +207,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box
if (shader == nullptr)
return;
const_cast<GLModel*>(&m_vbo_cone)->set_color(-1, color);
const_cast<GLModel*>(&m_cone)->set_color(-1, color);
if (!picking) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@ -220,7 +222,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box
glsafe(::glTranslated(0.0, 0.0, 2.0 * size));
glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size));
m_vbo_cone.render();
m_cone.render();
glsafe(::glPopMatrix());
if (! picking)

View File

@ -19,7 +19,7 @@ class GLGizmoMove3D : public GLGizmoBase
Vec3d m_starting_box_center;
Vec3d m_starting_box_bottom_center;
GLModel m_vbo_cone;
GLModel m_cone;
public:
GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);

View File

@ -18,13 +18,17 @@
namespace Slic3r::GUI {
std::shared_ptr<GLIndexedVertexArray> GLGizmoPainterBase::s_sphere = nullptr;
GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
{
// Make sphere and save it into a vertex buffer.
m_vbo_sphere.load_its_flat_shading(its_make_sphere(1., (2*M_PI)/24.));
m_vbo_sphere.finalize_geometry(true);
}
GLGizmoPainterBase::~GLGizmoPainterBase()
{
if (s_sphere != nullptr && s_sphere->has_VBOs())
s_sphere->release_geometry();
}
void GLGizmoPainterBase::set_painter_gizmo_data(const Selection& selection)
@ -184,6 +188,12 @@ void GLGizmoPainterBase::render_cursor_circle() const
void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
{
if (s_sphere == nullptr) {
s_sphere = std::make_shared<GLIndexedVertexArray>();
s_sphere->load_its_flat_shading(its_make_sphere(1.0, double(PI) / 12.0));
s_sphere->finalize_geometry(true);
}
const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse();
const bool is_left_handed = Geometry::Transformation(trafo).is_left_handed();
@ -204,7 +214,8 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
render_color = this->get_cursor_sphere_right_button_color();
glsafe(::glColor4fv(render_color.data()));
m_vbo_sphere.render();
assert(s_sphere != nullptr);
s_sphere->render();
if (is_left_handed)
glFrontFace(GL_CCW);

View File

@ -12,6 +12,7 @@
#include <cereal/types/vector.hpp>
#include <GL/glew.h>
#include <memory>
namespace Slic3r::GUI {
@ -112,7 +113,7 @@ private:
void on_render_for_picking() override {}
public:
GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
~GLGizmoPainterBase() override = default;
virtual ~GLGizmoPainterBase() override;
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);
@ -202,7 +203,7 @@ private:
const Camera& camera,
const std::vector<Transform3d>& trafo_matrices) const;
GLIndexedVertexArray m_vbo_sphere;
static std::shared_ptr<GLIndexedVertexArray> s_sphere;
bool m_internal_stack_active = false;
bool m_schedule_update = false;

View File

@ -39,20 +39,6 @@ GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis)
{
}
GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other)
: GLGizmoBase(other.m_parent, other.m_icon_filename, other.m_sprite_id)
, m_axis(other.m_axis)
, m_angle(other.m_angle)
, m_center(other.m_center)
, m_radius(other.m_radius)
, m_snap_coarse_in_radius(other.m_snap_coarse_in_radius)
, m_snap_coarse_out_radius(other.m_snap_coarse_out_radius)
, m_snap_fine_in_radius(other.m_snap_fine_in_radius)
, m_snap_fine_out_radius(other.m_snap_fine_out_radius)
{
}
void GLGizmoRotate::set_angle(double angle)
{
if (std::abs(angle - 2.0 * (double)PI) < EPSILON)
@ -130,6 +116,9 @@ void GLGizmoRotate::on_render()
if (!m_grabbers[0].enabled)
return;
if (!m_cone.is_initialized())
m_cone.init_from(its_make_cone(1.0, 1.0, double(PI) / 12.0));
const Selection& selection = m_parent.get_selection();
const BoundingBoxf3& box = selection.get_bounding_box();
@ -433,11 +422,8 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, cons
GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
, m_gizmos({ GLGizmoRotate(parent, GLGizmoRotate::X), GLGizmoRotate(parent, GLGizmoRotate::Y), GLGizmoRotate(parent, GLGizmoRotate::Z) })
{
m_gizmos.emplace_back(parent, GLGizmoRotate::X);
m_gizmos.emplace_back(parent, GLGizmoRotate::Y);
m_gizmos.emplace_back(parent, GLGizmoRotate::Z);
for (unsigned int i = 0; i < 3; ++i) {
m_gizmos[i].set_group_id(i);
}

View File

@ -4,7 +4,6 @@
#include "GLGizmoBase.hpp"
#include "../Jobs/RotoptimizeJob.hpp"
namespace Slic3r {
namespace GUI {
@ -40,9 +39,10 @@ private:
mutable float m_snap_fine_in_radius;
mutable float m_snap_fine_out_radius;
GLModel m_cone;
public:
GLGizmoRotate(GLCanvas3D& parent, Axis axis);
GLGizmoRotate(const GLGizmoRotate& other);
virtual ~GLGizmoRotate() = default;
double get_angle() const { return m_angle; }
@ -74,7 +74,7 @@ private:
class GLGizmoRotate3D : public GLGizmoBase
{
std::vector<GLGizmoRotate> m_gizmos;
std::array<GLGizmoRotate, 3> m_gizmos;
public:
GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);

View File

@ -77,6 +77,13 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
void GLGizmoSlaSupports::on_render()
{
if (!m_cone.is_initialized())
m_cone.init_from(its_make_cone(1.0, 1.0, double(PI) / 12.0));
if (!m_sphere.is_initialized())
m_sphere.init_from(its_make_sphere(1.0, double(PI) / 12.0));
if (!m_cylinder.is_initialized())
m_cylinder.init_from(its_make_cylinder(1.0, 1.0, double(PI) / 12.0));
ModelObject* mo = m_c->selection_info()->model_object();
const Selection& selection = m_parent.get_selection();

View File

@ -91,6 +91,10 @@ private:
std::vector<sla::SupportPoint> m_normal_cache; // to restore after discarding changes or undo/redo
ObjectID m_old_mo_id;
GLModel m_cone;
GLModel m_cylinder;
GLModel m_sphere;
// This map holds all translated description texts, so they can be easily referenced during layout calculations
// etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect.
std::map<std::string, wxString> m_desc;