Tech ENABLE_GCODE_VIEWER -> Selection curved arrows rendered using the new OpenGL model class

This commit is contained in:
enricoturri1966 2020-05-12 16:15:43 +02:00
parent 8d5cea82f4
commit 58258df113
6 changed files with 236 additions and 20 deletions

View File

@ -2002,6 +2002,7 @@ bool GLArrow::on_init()
return true;
}
#if !ENABLE_GCODE_VIEWER
GLCurvedArrow::GLCurvedArrow(unsigned int resolution)
: GLModel()
, m_resolution(resolution)
@ -2115,6 +2116,7 @@ bool GLCurvedArrow::on_init()
m_volume.indexed_vertex_array.finalize_geometry(true);
return true;
}
#endif // !ENABLE_GCODE_VIEWER
bool GLBed::on_init_from_file(const std::string& filename)
{

View File

@ -648,6 +648,7 @@ protected:
bool on_init() override;
};
#if !ENABLE_GCODE_VIEWER
class GLCurvedArrow : public GLModel
{
unsigned int m_resolution;
@ -658,6 +659,7 @@ public:
protected:
bool on_init() override;
};
#endif // !ENABLE_GCODE_VIEWER
class GLBed : public GLModel
{

View File

@ -11,7 +11,6 @@ namespace GUI {
void GL_Model::init_from(const GLModelInitializationData& data)
{
assert(!data.positions.empty() && !data.triangles.empty());
assert(data.positions.size() == data.normals.size());
@ -134,9 +133,16 @@ void GL_Model::send_to_gpu(const std::vector<float>& vertices, const std::vector
GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
{
auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) {
data.positions.emplace_back(position);
data.normals.emplace_back(normal);
};
resolution = std::max(4, resolution);
GLModelInitializationData data;
float angle_step = 2.0f * M_PI / static_cast<float>(resolution);
const float angle_step = 2.0f * M_PI / static_cast<float>(resolution);
std::vector<float> cosines(resolution);
std::vector<float> sines(resolution);
@ -147,15 +153,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float
sines[i] = -::sin(angle);
}
float total_height = tip_height + stem_height;
const float total_height = tip_height + stem_height;
// tip vertices/normals
data.positions.emplace_back(0.0f, 0.0f, total_height);
data.normals.emplace_back(Vec3f::UnitZ());
append_vertex(data, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ());
for (int i = 0; i < resolution; ++i)
{
data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], stem_height);
data.normals.emplace_back(sines[i], cosines[i], 0.0f);
append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f });
}
// tip triangles
@ -168,15 +172,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float
// tip cap outer perimeter vertices
for (int i = 0; i < resolution; ++i)
{
data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], stem_height);
data.normals.emplace_back(-Vec3f::UnitZ());
append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -Vec3f::UnitZ());
}
// tip cap inner perimeter vertices
for (int i = 0; i < resolution; ++i)
{
data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], stem_height);
data.normals.emplace_back(-Vec3f::UnitZ());
append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ());
}
// tip cap triangles
@ -191,15 +193,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float
// stem bottom vertices
for (int i = 0; i < resolution; ++i)
{
data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], stem_height);
data.normals.emplace_back(sines[i], cosines[i], 0.0f);
append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f });
}
// stem top vertices
for (int i = 0; i < resolution; ++i)
{
data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], 0.0f);
data.normals.emplace_back(sines[i], cosines[i], 0.0f);
append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f });
}
// stem triangles
@ -212,12 +212,10 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float
}
// stem cap vertices
data.positions.emplace_back(0.0f, 0.0f, 0.0f);
data.normals.emplace_back(-Vec3f::UnitZ());
append_vertex(data, Vec3f::Zero(), -Vec3f::UnitZ());
for (int i = 0; i < resolution; ++i)
{
data.positions.emplace_back(stem_radius* sines[i], stem_radius* cosines[i], 0.0f);
data.normals.emplace_back(-Vec3f::UnitZ());
append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ());
}
// stem cap triangles
@ -230,5 +228,153 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float
return data;
}
GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness)
{
auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) {
data.positions.emplace_back(position);
data.normals.emplace_back(normal);
};
resolution = std::max(2, resolution);
GLModelInitializationData data;
const float half_thickness = 0.5f * thickness;
const float half_stem_width = 0.5f * stem_width;
const float half_tip_width = 0.5f * tip_width;
const float outer_radius = radius + half_stem_width;
const float inner_radius = radius - half_stem_width;
const float step_angle = 0.5f * PI / static_cast<float>(resolution);
// tip
// top face vertices
append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ());
append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitZ());
append_vertex(data, { -tip_height, radius, half_thickness }, Vec3f::UnitZ());
append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitZ());
append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitZ());
// top face triangles
data.triangles.emplace_back(0, 1, 2);
data.triangles.emplace_back(0, 2, 4);
data.triangles.emplace_back(4, 2, 3);
// bottom face vertices
append_vertex(data, { 0.0f, outer_radius, -half_thickness }, -Vec3f::UnitZ());
append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, -Vec3f::UnitZ());
append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitZ());
append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitZ());
append_vertex(data, { 0.0f, inner_radius, -half_thickness }, -Vec3f::UnitZ());
// bottom face triangles
data.triangles.emplace_back(5, 7, 6);
data.triangles.emplace_back(5, 9, 7);
data.triangles.emplace_back(9, 8, 7);
// side faces vertices
append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX());
append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitY());
append_vertex(data, { -tip_height, radius, half_thickness }, -Vec3f::UnitX());
append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, -Vec3f::UnitY());
append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX());
append_vertex(data, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX());
append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitY());
append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitX());
append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitY());
append_vertex(data, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX());
// side faces triangles
for (int i = 0; i < 4; ++i)
{
data.triangles.emplace_back(15 + i, 11 + i, 10 + i);
data.triangles.emplace_back(15 + i, 16 + i, 11 + i);
}
// stem
// top face vertices
for (int i = 0; i <= resolution; ++i)
{
float angle = static_cast<float>(i) * step_angle;
append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ());
}
for (int i = 0; i <= resolution; ++i)
{
float angle = static_cast<float>(i) * step_angle;
append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ());
}
// top face triangles
for (int i = 0; i < resolution; ++i)
{
data.triangles.emplace_back(20 + i, 21 + i, 21 + resolution + i);
data.triangles.emplace_back(21 + i, 22 + resolution + i, 21 + resolution + i);
}
// bottom face vertices
for (int i = 0; i <= resolution; ++i)
{
float angle = static_cast<float>(i) * step_angle;
append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ());
}
for (int i = 0; i <= resolution; ++i)
{
float angle = static_cast<float>(i) * step_angle;
append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ());
}
// bottom face triangles
for (int i = 0; i < resolution; ++i)
{
data.triangles.emplace_back(22 + 2 * resolution + i, 23 + 3 * resolution + i, 23 + 2 * resolution + i);
data.triangles.emplace_back(23 + 2 * resolution + i, 23 + 3 * resolution + i, 24 + 3 * resolution + i);
}
// side faces vertices
for (int i = 0; i <= resolution; ++i)
{
float angle = static_cast<float>(i) * step_angle;
float c = ::cos(angle);
float s = ::sin(angle);
append_vertex(data, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f});
}
for (int i = resolution; i >= 0; --i)
{
float angle = static_cast<float>(i) * step_angle;
float c = ::cos(angle);
float s = ::sin(angle);
append_vertex(data, { outer_radius * s, outer_radius * c, half_thickness }, { s, c, 0.0f });
}
for (int i = 0; i <= resolution; ++i)
{
float angle = static_cast<float>(i) * step_angle;
float c = ::cos(angle);
float s = ::sin(angle);
append_vertex(data, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f });
}
for (int i = resolution; i >= 0; --i)
{
float angle = static_cast<float>(i) * step_angle;
float c = ::cos(angle);
float s = ::sin(angle);
append_vertex(data, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f });
}
// side faces triangles
for (int i = 0; i < 2 * resolution + 1; ++i)
{
data.triangles.emplace_back(20 + 6 * (resolution + 1) + i, 21 + 6 * (resolution + 1) + i, 21 + 4 * (resolution + 1) + i);
data.triangles.emplace_back(20 + 6 * (resolution + 1) + i, 21 + 4 * (resolution + 1) + i, 20 + 4 * (resolution + 1) + i);
}
return data;
}
} // namespace GUI
} // namespace Slic3r

View File

@ -47,6 +47,11 @@ namespace GUI {
GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height,
float stem_radius, float stem_height);
// create an arrow whose stem is a quarter of circle, with the given dimensions and resolution
// the origin of the arrow is in the center of the circle
// the arrow is contained in the 1st quadrant and is pointing counterclockwise
GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);
} // namespace GUI
} // namespace Slic3r

View File

@ -13,6 +13,9 @@
#include <GL/glew.h>
#include <boost/algorithm/string/predicate.hpp>
#if ENABLE_GCODE_VIEWER
#include <boost/log/trivial.hpp>
#endif // ENABLE_GCODE_VIEWER
static const float UNIFORM_SCALE_COLOR[3] = { 1.0f, 0.38f, 0.0f };
@ -76,7 +79,9 @@ Selection::Selection()
, m_mode(Instance)
, m_type(Empty)
, m_valid(false)
#if !ENABLE_GCODE_VIEWER
, m_curved_arrow(16)
#endif // !ENABLE_GCODE_VIEWER
, m_scale_factor(1.0f)
{
this->set_bounding_boxes_dirty();
@ -109,10 +114,21 @@ bool Selection::init()
m_arrow.set_scale(5.0 * Vec3d::Ones());
#if ENABLE_GCODE_VIEWER
m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f));
if (!m_arrows_shader.init("gouraud_light.vs", "gouraud_light.fs"))
{
BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available";
return false;
}
#else
if (!m_curved_arrow.init())
return false;
m_curved_arrow.set_scale(5.0 * Vec3d::Ones());
#endif //ENABLE_GCODE_VIEWER
return true;
}
@ -1927,6 +1943,40 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field)
void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const
{
#if ENABLE_GCODE_VIEWER
if (!m_arrows_shader.is_initialized())
return;
m_arrows_shader.start_using();
GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color");
if (boost::ends_with(sidebar_field, "x"))
{
if (color_id >= 0)
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0]));
glsafe(::glRotated(90.0, 0.0, 1.0, 0.0));
render_sidebar_rotation_hint(X);
}
else if (boost::ends_with(sidebar_field, "y"))
{
if (color_id >= 0)
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1]));
glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
render_sidebar_rotation_hint(Y);
}
else if (boost::ends_with(sidebar_field, "z"))
{
if (color_id >= 0)
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2]));
render_sidebar_rotation_hint(Z);
}
m_arrows_shader.stop_using();
#else
if (boost::ends_with(sidebar_field, "x"))
{
glsafe(::glRotated(90.0, 0.0, 1.0, 0.0));
@ -1939,6 +1989,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field)
}
else if (boost::ends_with(sidebar_field, "z"))
render_sidebar_rotation_hint(Z);
#endif // ENABLE_GCODE_VIEWER
}
void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const
@ -2054,9 +2105,10 @@ void Selection::render_sidebar_position_hint(Axis axis) const
void Selection::render_sidebar_rotation_hint(Axis axis) const
{
#if !ENABLE_GCODE_VIEWER
m_curved_arrow.set_color(AXES_COLOR[axis], 3);
#endif // !ENABLE_GCODE_VIEWER
m_curved_arrow.render();
glsafe(::glRotated(180.0, 0.0, 0.0, 1.0));
m_curved_arrow.render();
}

View File

@ -4,6 +4,10 @@
#include <set>
#include "libslic3r/Geometry.hpp"
#include "3DScene.hpp"
#if ENABLE_GCODE_VIEWER
#include "GLModel.hpp"
#include "GLShader.hpp"
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_RENDER_SELECTION_CENTER
class GLUquadric;
@ -201,7 +205,12 @@ private:
GLUquadricObj* m_quadric;
#endif // ENABLE_RENDER_SELECTION_CENTER
mutable GLArrow m_arrow;
#if ENABLE_GCODE_VIEWER
GL_Model m_curved_arrow;
Shader m_arrows_shader;
#else
mutable GLCurvedArrow m_curved_arrow;
#endif // ENABLE_GCODE_VIEWER
mutable float m_scale_factor;