Visual hints in the 3D scene when sidebar matrix fields have focus (wip [position+scale+size] and disabled)

This commit is contained in:
Enrico Turri 2018-12-19 14:44:37 +01:00
parent b7c506170d
commit 0dcdcf74fc
5 changed files with 374 additions and 0 deletions

View File

@ -42,6 +42,8 @@
#define ENABLE_TOOLBAR_BACKGROUND_TEXTURE (1 && ENABLE_1_42_0)
// Renders a small sphere in the center of the bounding box of the current selection when no gizmo is active
#define ENABLE_RENDER_SELECTION_CENTER (0 && ENABLE_1_42_0)
// Show visual hints in the 3D scene when sidebar matrix fields have focus
#define ENABLE_SIDEBAR_VISUAL_HINTS (0 && ENABLE_1_42_0)
#endif // _technologies_h_

View File

@ -1868,6 +1868,130 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height
GUI::GLCanvas3DManager _3DScene::s_canvas_mgr;
#if ENABLE_SIDEBAR_VISUAL_HINTS
GLModel::GLModel()
: m_useVBOs(false)
{
}
GLModel::~GLModel()
{
m_volume.release_geometry();
}
void GLModel::set_color(float* color, unsigned int size)
{
m_volume.set_render_color(color, size);
}
void GLModel::set_scale(const Vec3d& scale)
{
m_volume.set_volume_scaling_factor(scale);
}
void GLModel::render() const
{
if (m_useVBOs)
render_VBOs();
else
{
}
}
void GLModel::render_VBOs() const
{
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
::glCullFace(GL_BACK);
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
GLint current_program_id;
::glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id);
GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1;
m_volume.render_VBOs(color_id, -1, -1);
::glBindBuffer(GL_ARRAY_BUFFER, 0);
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
::glDisable(GL_BLEND);
}
GLArrow::GLArrow()
: GLModel()
{
}
bool GLArrow::on_init(bool useVBOs)
{
Pointf3s vertices;
std::vector<Vec3crd> triangles;
// top face
vertices.emplace_back(0.5, 0.0, -0.1);
vertices.emplace_back(0.5, 2.0, -0.1);
vertices.emplace_back(1.0, 2.0, -0.1);
vertices.emplace_back(0.0, 3.0, -0.1);
vertices.emplace_back(-1.0, 2.0, -0.1);
vertices.emplace_back(-0.5, 2.0, -0.1);
vertices.emplace_back(-0.5, 0.0, -0.1);
// bottom face
vertices.emplace_back(0.5, 0.0, 0.1);
vertices.emplace_back(0.5, 2.0, 0.1);
vertices.emplace_back(1.0, 2.0, 0.1);
vertices.emplace_back(0.0, 3.0, 0.1);
vertices.emplace_back(-1.0, 2.0, 0.1);
vertices.emplace_back(-0.5, 2.0, 0.1);
vertices.emplace_back(-0.5, 0.0, 0.1);
// bottom face
triangles.emplace_back(0, 6, 1);
triangles.emplace_back(6, 5, 1);
triangles.emplace_back(5, 4, 3);
triangles.emplace_back(5, 3, 1);
triangles.emplace_back(1, 3, 2);
// top face
triangles.emplace_back(7, 8, 13);
triangles.emplace_back(13, 8, 12);
triangles.emplace_back(12, 10, 11);
triangles.emplace_back(8, 10, 12);
triangles.emplace_back(8, 9, 10);
// side face
triangles.emplace_back(0, 1, 8);
triangles.emplace_back(8, 7, 0);
triangles.emplace_back(1, 2, 9);
triangles.emplace_back(9, 8, 1);
triangles.emplace_back(2, 3, 10);
triangles.emplace_back(10, 9, 2);
triangles.emplace_back(3, 4, 11);
triangles.emplace_back(11, 10, 3);
triangles.emplace_back(4, 5, 12);
triangles.emplace_back(12, 11, 4);
triangles.emplace_back(5, 6, 13);
triangles.emplace_back(13, 12, 5);
triangles.emplace_back(6, 0, 7);
triangles.emplace_back(7, 13, 6);
m_useVBOs = useVBOs;
if (m_useVBOs)
m_volume.indexed_vertex_array.load_mesh_full_shading(TriangleMesh(vertices, triangles));
else
m_volume.indexed_vertex_array.load_mesh_flat_shading(TriangleMesh(vertices, triangles));
m_volume.finalize_geometry(m_useVBOs);
return true;
}
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
std::string _3DScene::get_gl_info(bool format_as_html, bool extensions)
{
return s_canvas_mgr.get_gl_info(format_as_html, extensions);

View File

@ -583,6 +583,41 @@ private:
GLVolumeCollection& operator=(const GLVolumeCollection &);
};
#if ENABLE_SIDEBAR_VISUAL_HINTS
class GLModel
{
protected:
GLVolume m_volume;
bool m_useVBOs;
public:
GLModel();
virtual ~GLModel();
bool init(bool useVBOs) { return on_init(useVBOs); }
void set_color(float* color, unsigned int size);
void set_scale(const Vec3d& scale);
void render() const;
protected:
virtual bool on_init(bool useVBOs) = 0;
private:
void render_VBOs() const;
};
class GLArrow : public GLModel
{
public:
GLArrow();
protected:
virtual bool on_init(bool useVBOs);
};
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
class _3DScene
{
static GUI::GLCanvas3DManager s_canvas_mgr;

View File

@ -1154,6 +1154,12 @@ GLCanvas3D::Selection::VolumeCache::VolumeCache(const Vec3d& position, const Vec
}
#endif // ENABLE_MODELVOLUME_TRANSFORM
#if ENABLE_SIDEBAR_VISUAL_HINTS
const float GLCanvas3D::Selection::RED[3] = { 1.0f, 0.0f, 0.0f };
const float GLCanvas3D::Selection::GREEN[3] = { 0.0f, 1.0f, 0.0f };
const float GLCanvas3D::Selection::BLUE[3] = { 0.0f, 0.0f, 1.0f };
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
GLCanvas3D::Selection::Selection()
: m_volumes(nullptr)
, m_model(nullptr)
@ -1183,6 +1189,19 @@ void GLCanvas3D::Selection::set_volumes(GLVolumePtrs* volumes)
_update_valid();
}
#if ENABLE_SIDEBAR_VISUAL_HINTS
bool GLCanvas3D::Selection::init(bool useVBOs)
{
if (m_arrow.init(useVBOs))
{
m_arrow.set_scale(5.0 * Vec3d::Ones());
return true;
}
return false;
}
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
void GLCanvas3D::Selection::set_model(Model* model)
{
m_model = model;
@ -2055,6 +2074,50 @@ void GLCanvas3D::Selection::render_center() const
}
#endif // ENABLE_RENDER_SELECTION_CENTER
#if ENABLE_SIDEBAR_VISUAL_HINTS
void GLCanvas3D::Selection::render_sidebar_hints(const std::string& sidebar_field) const
{
if (sidebar_field.empty())
return;
::glClear(GL_DEPTH_BUFFER_BIT);
::glEnable(GL_DEPTH_TEST);
::glEnable(GL_LIGHTING);
::glPushMatrix();
const Vec3d& center = get_bounding_box().center();
if (is_single_full_instance())
::glTranslated(center(0), center(1), center(2));
else if (is_single_volume() || is_single_modifier())
{
const GLVolume* volume = (*m_volumes)[*m_list.begin()];
Transform3d orient_matrix = volume->get_instance_transformation().get_matrix(true, false, true, true) * volume->get_volume_transformation().get_matrix(true, false, true, true);
const Vec3d& offset = get_bounding_box().center();
::glTranslated(offset(0), offset(1), offset(2));
::glMultMatrixd(orient_matrix.data());
}
else
::glTranslated(center(0), center(1), center(2));
if (boost::starts_with(sidebar_field, "position"))
_render_sidebar_position_hints(sidebar_field);
else if (boost::starts_with(sidebar_field, "rotation"))
_render_sidebar_rotation_hints(sidebar_field);
else if (boost::starts_with(sidebar_field, "scale"))
_render_sidebar_scale_hints(sidebar_field);
else if (boost::starts_with(sidebar_field, "size"))
_render_sidebar_size_hints(sidebar_field);
::glPopMatrix();
::glDisable(GL_LIGHTING);
}
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
void GLCanvas3D::Selection::_update_valid()
{
m_valid = (m_volumes != nullptr) && (m_model != nullptr);
@ -2457,6 +2520,101 @@ void GLCanvas3D::Selection::_render_bounding_box(const BoundingBoxf3& box, float
::glEnd();
}
#if ENABLE_SIDEBAR_VISUAL_HINTS
void GLCanvas3D::Selection::_render_sidebar_position_hints(const std::string& sidebar_field) const
{
if (boost::ends_with(sidebar_field, "x"))
{
::glRotated(-90.0, 0.0, 0.0, 1.0);
_render_sidebar_position_hint(X);
}
else if (boost::ends_with(sidebar_field, "y"))
_render_sidebar_position_hint(Y);
else if (boost::ends_with(sidebar_field, "z"))
{
::glRotated(90.0, 1.0, 0.0, 0.0);
_render_sidebar_position_hint(Z);
}
}
void GLCanvas3D::Selection::_render_sidebar_rotation_hints(const std::string& sidebar_field) const
{
}
void GLCanvas3D::Selection::_render_sidebar_scale_hints(const std::string& sidebar_field) const
{
if (boost::ends_with(sidebar_field, "x") || requires_uniform_scale())
{
::glPushMatrix();
::glRotated(-90.0, 0.0, 0.0, 1.0);
_render_sidebar_scale_hint(X);
::glPopMatrix();
}
if (boost::ends_with(sidebar_field, "y") || requires_uniform_scale())
{
::glPushMatrix();
_render_sidebar_scale_hint(Y);
::glPopMatrix();
}
if (boost::ends_with(sidebar_field, "z") || requires_uniform_scale())
{
::glPushMatrix();
::glRotated(90.0, 1.0, 0.0, 0.0);
_render_sidebar_scale_hint(Z);
::glPopMatrix();
}
}
void GLCanvas3D::Selection::_render_sidebar_size_hints(const std::string& sidebar_field) const
{
_render_sidebar_scale_hints(sidebar_field);
}
void GLCanvas3D::Selection::_render_sidebar_position_hint(Axis axis) const
{
float color[3];
switch (axis)
{
case X: { ::memcpy((void*)color, (const void*)RED, 3 * sizeof(float)); break; }
case Y: { ::memcpy((void*)color, (const void*)GREEN, 3 * sizeof(float)); break; }
case Z: { ::memcpy((void*)color, (const void*)BLUE, 3 * sizeof(float)); break; }
}
m_arrow.set_color(color, 3);
m_arrow.render();
}
void GLCanvas3D::Selection::_render_sidebar_rotation_hint(Axis axis, double length) const
{
}
void GLCanvas3D::Selection::_render_sidebar_scale_hint(Axis axis) const
{
float color[3];
switch (axis)
{
case X: { ::memcpy((void*)color, (const void*)RED, 3 * sizeof(float)); break; }
case Y: { ::memcpy((void*)color, (const void*)GREEN, 3 * sizeof(float)); break; }
case Z: { ::memcpy((void*)color, (const void*)BLUE, 3 * sizeof(float)); break; }
}
m_arrow.set_color(color, 3);
::glTranslated(0.0, 5.0, 0.0);
m_arrow.render();
::glTranslated(0.0, -10.0, 0.0);
::glRotated(180.0, 0.0, 0.0, 1.0);
m_arrow.render();
}
void GLCanvas3D::Selection::_render_sidebar_size_hint(Axis axis, double length) const
{
}
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
void GLCanvas3D::Selection::_synchronize_unselected_instances()
{
std::set<unsigned int> done; // prevent processing volumes twice
@ -3788,6 +3946,11 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl)
if (!_init_toolbar())
return false;
#if ENABLE_SIDEBAR_VISUAL_HINTS
if (!m_selection.init(m_use_VBOs))
return false;
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
#if ENABLE_REMOVE_TABS_FROM_PLATER
post_event(SimpleEvent(EVT_GLCANVAS_INIT));
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
@ -4165,6 +4328,10 @@ void GLCanvas3D::render()
// this position is used later into on_mouse() to drag the objects
m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast<int>());
#if ENABLE_SIDEBAR_VISUAL_HINTS
_render_selection_sidebar_hints();
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
_render_current_gizmo();
#if ENABLE_SHOW_CAMERA_TARGET
_render_camera_target();
@ -5671,6 +5838,11 @@ bool GLCanvas3D::_init_toolbar()
icons_data.icon_border_size = 1;
icons_data.icon_gap_size = 1;
// icons_data.filename = "toolbar141.png";
// icons_data.icon_size = 52;
// icons_data.icon_border_size = 0;
// icons_data.icon_gap_size = 0;
BackgroundTexture::Metadata background_data;
background_data.filename = "toolbar_background.png";
background_data.left = 16;
@ -6577,6 +6749,19 @@ void GLCanvas3D::_render_sla_slices() const
}
}
#if ENABLE_SIDEBAR_VISUAL_HINTS
void GLCanvas3D::_render_selection_sidebar_hints() const
{
if (m_use_VBOs)
m_shader.start_using();
m_selection.render_sidebar_hints(m_sidebar_field);
if (m_use_VBOs)
m_shader.stop_using();
}
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
void GLCanvas3D::_update_volumes_hover_state() const
{
for (GLVolume* v : m_volumes.volumes)

View File

@ -368,6 +368,12 @@ class GLCanvas3D
public:
class Selection
{
#if ENABLE_SIDEBAR_VISUAL_HINTS
static const float RED[3];
static const float GREEN[3];
static const float BLUE[3];
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
public:
typedef std::set<unsigned int> IndicesList;
@ -495,6 +501,9 @@ public:
#if ENABLE_RENDER_SELECTION_CENTER
GLUquadricObj* m_quadric;
#endif // ENABLE_RENDER_SELECTION_CENTER
#if ENABLE_SIDEBAR_VISUAL_HINTS
mutable GLArrow m_arrow;
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
public:
Selection();
@ -503,6 +512,9 @@ public:
#endif // ENABLE_RENDER_SELECTION_CENTER
void set_volumes(GLVolumePtrs* volumes);
#if ENABLE_SIDEBAR_VISUAL_HINTS
bool init(bool useVBOs);
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
Model* get_model() const { return m_model; }
void set_model(Model* model);
@ -580,6 +592,9 @@ public:
#if ENABLE_RENDER_SELECTION_CENTER
void render_center() const;
#endif // ENABLE_RENDER_SELECTION_CENTER
#if ENABLE_SIDEBAR_VISUAL_HINTS
void render_sidebar_hints(const std::string& sidebar_field) const;
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
private:
void _update_valid();
@ -595,6 +610,16 @@ public:
void _render_selected_volumes() const;
void _render_synchronized_volumes() const;
void _render_bounding_box(const BoundingBoxf3& box, float* color) const;
#if ENABLE_SIDEBAR_VISUAL_HINTS
void _render_sidebar_position_hints(const std::string& sidebar_field) const;
void _render_sidebar_rotation_hints(const std::string& sidebar_field) const;
void _render_sidebar_scale_hints(const std::string& sidebar_field) const;
void _render_sidebar_size_hints(const std::string& sidebar_field) const;
void _render_sidebar_position_hint(Axis axis) const;
void _render_sidebar_rotation_hint(Axis axis, double length) const;
void _render_sidebar_scale_hint(Axis axis) const;
void _render_sidebar_size_hint(Axis axis, double length) const;
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
void _synchronize_unselected_instances();
void _synchronize_unselected_volumes();
#if ENABLE_ENSURE_ON_BED_WHILE_SCALING
@ -1055,6 +1080,9 @@ private:
void _render_camera_target() const;
#endif // ENABLE_SHOW_CAMERA_TARGET
void _render_sla_slices() const;
#if ENABLE_SIDEBAR_VISUAL_HINTS
void _render_selection_sidebar_hints() const;
#endif // ENABLE_SIDEBAR_VISUAL_HINTS
void _update_volumes_hover_state() const;
void _update_gizmos_data();