ENABLE_GCODE_VIEWER -> Completed implementation of new GLModel class

This commit is contained in:
enricoturri1966 2020-05-27 08:06:02 +02:00
parent 8f91b4f4f4
commit aa04f0e555
8 changed files with 105 additions and 44 deletions

View File

@ -358,14 +358,23 @@ void Bed3D::calc_bounding_boxes() const
// extend to contain axes
#if ENABLE_GCODE_VIEWER
m_extended_bounding_box.merge(m_axes.get_total_length() * Vec3d::Ones());
#else
m_extended_bounding_box.merge(m_axes.length + Axes::ArrowLength * Vec3d::Ones());
#endif // ENABLE_GCODE_VIEWER
m_extended_bounding_box.merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones());
m_extended_bounding_box.merge(m_extended_bounding_box.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, m_extended_bounding_box.max(2)));
// extend to contain model, if any
BoundingBoxf3 model_bb = m_model.get_bounding_box();
if (model_bb.defined)
{
model_bb.translate(m_model_offset);
m_extended_bounding_box.merge(model_bb);
}
#else
m_extended_bounding_box.merge(m_axes.get_total_length() * Vec3d::Ones());
m_extended_bounding_box.merge(m_axes.length + Axes::ArrowLength * Vec3d::Ones());
// extend to contain model, if any
if (!m_model.get_filename().empty())
m_extended_bounding_box.merge(m_model.get_transformed_bounding_box());
#endif // ENABLE_GCODE_VIEWER
}
void Bed3D::calc_triangles(const ExPolygon& poly)
@ -621,7 +630,11 @@ void Bed3D::render_model() const
// move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
Vec3d shift = m_bounding_box.center();
shift(2) = -0.03;
#if ENABLE_GCODE_VIEWER
m_model_offset = shift;
#else
m_model.set_offset(shift);
#endif // ENABLE_GCODE_VIEWER
// update extended bounding box
calc_bounding_boxes();
@ -633,7 +646,15 @@ void Bed3D::render_model() const
if (shader != nullptr)
{
shader->start_using();
#if ENABLE_GCODE_VIEWER
shader->set_uniform("uniform_color", m_model_color);
::glPushMatrix();
::glTranslated(m_model_offset(0), m_model_offset(1), m_model_offset(2));
#endif // ENABLE_GCODE_VIEWER
m_model.render();
#if ENABLE_GCODE_VIEWER
::glPopMatrix();
#endif // ENABLE_GCODE_VIEWER
shader->stop_using();
}
}

View File

@ -8,6 +8,9 @@
#endif // ENABLE_GCODE_VIEWER
#include <tuple>
#if ENABLE_GCODE_VIEWER
#include <array>
#endif // ENABLE_GCODE_VIEWER
#if !ENABLE_GCODE_VIEWER
class GLUquadric;
@ -52,10 +55,13 @@ class Bed3D
#if ENABLE_GCODE_VIEWER
class Axes
{
public:
static const float DefaultStemRadius;
static const float DefaultStemLength;
static const float DefaultTipRadius;
static const float DefaultTipLength;
private:
#else
struct Axes
{
@ -67,7 +73,7 @@ class Bed3D
#if ENABLE_GCODE_VIEWER
Vec3d m_origin{ Vec3d::Zero() };
float m_stem_length{ DefaultStemLength };
mutable GL_Model m_arrow;
mutable GLModel m_arrow;
public:
#else
@ -82,6 +88,7 @@ class Bed3D
#endif // !ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
const Vec3d& get_origin() const { return m_origin; }
void set_origin(const Vec3d& origin) { m_origin = origin; }
void set_stem_length(float length);
float get_total_length() const { return m_stem_length + DefaultTipLength; }
@ -113,7 +120,13 @@ private:
GeometryBuffer m_triangles;
GeometryBuffer m_gridlines;
mutable GLTexture m_texture;
#if ENABLE_GCODE_VIEWER
mutable GLModel m_model;
mutable Vec3d m_model_offset{ Vec3d::Zero() };
std::array<float, 4> m_model_color{ 0.235f, 0.235f, 0.235f, 1.0f };
#else
mutable GLBed m_model;
#endif // ENABLE_GCODE_VIEWER
// temporary texture shown until the main texture has still no levels compressed
mutable GLTexture m_temp_texture;
mutable unsigned int m_vbo_id;

View File

@ -1822,6 +1822,7 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height
thick_point_to_verts(point, width, height, volume);
}
#if !ENABLE_GCODE_VIEWER
GLModel::GLModel()
: m_filename("")
{
@ -1904,7 +1905,6 @@ void GLModel::render() const
glsafe(::glDisable(GL_BLEND));
}
#if !ENABLE_GCODE_VIEWER
bool GLArrow::on_init()
{
Pointf3s vertices;
@ -2076,7 +2076,6 @@ 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)
{
@ -2108,5 +2107,6 @@ bool GLBed::on_init_from_file(const std::string& filename)
return true;
}
#endif // !ENABLE_GCODE_VIEWER
} // namespace Slic3r

View File

@ -599,6 +599,7 @@ private:
GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = nullptr);
#if !ENABLE_GCODE_VIEWER
class GLModel
{
protected:
@ -636,7 +637,6 @@ protected:
virtual bool on_init_from_file(const std::string& filename) { return false; }
};
#if !ENABLE_GCODE_VIEWER
class GLArrow : public GLModel
{
protected:
@ -653,13 +653,13 @@ public:
protected:
bool on_init() override;
};
#endif // !ENABLE_GCODE_VIEWER
class GLBed : public GLModel
{
protected:
bool on_init_from_file(const std::string& filename) override;
};
#endif // !ENABLE_GCODE_VIEWER
struct _3DScene
{

View File

@ -219,7 +219,7 @@ public:
{
class Marker
{
GL_Model m_model;
GLModel m_model;
Transform3f m_world_transform;
BoundingBoxf3 m_world_bounding_box;
std::array<float, 4> m_color{ 1.0f, 1.0f, 1.0f, 1.0f };

View File

@ -3,13 +3,17 @@
#include "3DScene.hpp"
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Model.hpp"
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <GL/glew.h>
namespace Slic3r {
namespace GUI {
void GL_Model::init_from(const GLModelInitializationData& data)
void GLModel::init_from(const GLModelInitializationData& data)
{
assert(!data.positions.empty() && !data.triangles.empty());
assert(data.positions.size() == data.normals.size());
@ -20,8 +24,9 @@ void GL_Model::init_from(const GLModelInitializationData& data)
// vertices/normals data
std::vector<float> vertices(6 * data.positions.size());
for (size_t i = 0; i < data.positions.size(); ++i) {
::memcpy(static_cast<void*>(&vertices[i * 6]), static_cast<const void*>(data.positions[i].data()), 3 * sizeof(float));
::memcpy(static_cast<void*>(&vertices[3 + i * 6]), static_cast<const void*>(data.normals[i].data()), 3 * sizeof(float));
size_t offset = i * 6;
::memcpy(static_cast<void*>(&vertices[offset]), static_cast<const void*>(data.positions[i].data()), 3 * sizeof(float));
::memcpy(static_cast<void*>(&vertices[3 + offset]), static_cast<const void*>(data.normals[i].data()), 3 * sizeof(float));
}
// indices data
@ -41,34 +46,26 @@ void GL_Model::init_from(const GLModelInitializationData& data)
send_to_gpu(vertices, indices);
}
void GL_Model::init_from(const TriangleMesh& mesh)
void GLModel::init_from(const TriangleMesh& mesh)
{
auto get_normal = [](const std::array<stl_vertex, 3>& triangle) {
return (triangle[1] - triangle[0]).cross(triangle[2] - triangle[0]).normalized();
};
if (m_vbo_id > 0) // call reset() if you want to reuse this model
return;
assert(!mesh.its.vertices.empty() && !mesh.its.indices.empty()); // call require_shared_vertices() before to pass the mesh to this method
std::vector<float> vertices = std::vector<float>(18 * mesh.stl.stats.number_of_facets);
std::vector<unsigned int> indices = std::vector<unsigned int>(3 * mesh.stl.stats.number_of_facets);
// vertices data -> load from mesh
std::vector<float> vertices(6 * mesh.its.vertices.size());
for (size_t i = 0; i < mesh.its.vertices.size(); ++i) {
::memcpy(static_cast<void*>(&vertices[i * 6]), static_cast<const void*>(mesh.its.vertices[i].data()), 3 * sizeof(float));
}
// indices/normals data -> load from mesh
std::vector<unsigned int> indices(3 * mesh.its.indices.size());
for (size_t i = 0; i < mesh.its.indices.size(); ++i) {
const stl_triangle_vertex_indices& triangle = mesh.its.indices[i];
for (size_t j = 0; j < 3; ++j) {
indices[i * 3 + j] = static_cast<unsigned int>(triangle[j]);
unsigned int vertices_count = 0;
for (uint32_t i = 0; i < mesh.stl.stats.number_of_facets; ++i) {
const stl_facet& facet = mesh.stl.facet_start[i];
for (uint32_t j = 0; j < 3; ++j) {
uint32_t offset = i * 18 + j * 6;
::memcpy(static_cast<void*>(&vertices[offset]), static_cast<const void*>(facet.vertex[j].data()), 3 * sizeof(float));
::memcpy(static_cast<void*>(&vertices[3 + offset]), static_cast<const void*>(facet.normal.data()), 3 * sizeof(float));
}
Vec3f normal = get_normal({ mesh.its.vertices[triangle[0]], mesh.its.vertices[triangle[1]], mesh.its.vertices[triangle[2]] });
::memcpy(static_cast<void*>(&vertices[3 + static_cast<size_t>(triangle[0]) * 6]), static_cast<const void*>(normal.data()), 3 * sizeof(float));
::memcpy(static_cast<void*>(&vertices[3 + static_cast<size_t>(triangle[1]) * 6]), static_cast<const void*>(normal.data()), 3 * sizeof(float));
::memcpy(static_cast<void*>(&vertices[3 + static_cast<size_t>(triangle[2]) * 6]), static_cast<const void*>(normal.data()), 3 * sizeof(float));
for (uint32_t j = 0; j < 3; ++j) {
indices[i * 3 + j] = vertices_count + j;
}
vertices_count += 3;
}
m_indices_count = static_cast<unsigned int>(indices.size());
@ -77,7 +74,32 @@ void GL_Model::init_from(const TriangleMesh& mesh)
send_to_gpu(vertices, indices);
}
void GL_Model::reset()
bool GLModel::init_from_file(const std::string& filename)
{
if (!boost::filesystem::exists(filename))
return false;
if (!boost::algorithm::iends_with(filename, ".stl"))
return false;
Model model;
try
{
model = Model::read_from_file(filename);
}
catch (std::exception&)
{
return false;
}
init_from(model.mesh());
m_filename = filename;
return true;
}
void GLModel::reset()
{
// release gpu memory
if (m_ibo_id > 0) {
@ -92,9 +114,10 @@ void GL_Model::reset()
m_indices_count = 0;
m_bounding_box = BoundingBoxf3();
m_filename = std::string();
}
void GL_Model::render() const
void GLModel::render() const
{
if (m_vbo_id == 0 || m_ibo_id == 0)
return;
@ -116,7 +139,7 @@ void GL_Model::render() const
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
void GL_Model::send_to_gpu(const std::vector<float>& vertices, const std::vector<unsigned int>& indices)
void GLModel::send_to_gpu(const std::vector<float>& vertices, const std::vector<unsigned int>& indices)
{
// vertex data -> send to gpu
glsafe(::glGenBuffers(1, &m_vbo_id));

View File

@ -4,6 +4,7 @@
#include "libslic3r/Point.hpp"
#include "libslic3r/BoundingBox.hpp"
#include <vector>
#include <string>
namespace Slic3r {
@ -18,24 +19,28 @@ namespace GUI {
std::vector<Vec3i> triangles;
};
class GL_Model
class GLModel
{
unsigned int m_vbo_id{ 0 };
unsigned int m_ibo_id{ 0 };
size_t m_indices_count{ 0 };
BoundingBoxf3 m_bounding_box;
std::string m_filename;
public:
virtual ~GL_Model() { reset(); }
virtual ~GLModel() { reset(); }
void init_from(const GLModelInitializationData& data);
void init_from(const TriangleMesh& mesh);
bool init_from_file(const std::string& filename);
void reset();
void render() const;
const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; }
const std::string& get_filename() const { return m_filename; }
private:
void send_to_gpu(const std::vector<float>& vertices, const std::vector<unsigned int>& indices);
};
@ -44,8 +49,7 @@ namespace GUI {
// create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
// the origin of the arrow is in the center of the stem cap
// the arrow has its axis of symmetry along the Z axis and is pointing upward
GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height,
float stem_radius, float stem_height);
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

View File

@ -207,8 +207,8 @@ private:
GLUquadricObj* m_quadric;
#endif // ENABLE_RENDER_SELECTION_CENTER
#if ENABLE_GCODE_VIEWER
GL_Model m_arrow;
GL_Model m_curved_arrow;
GLModel m_arrow;
GLModel m_curved_arrow;
#else
mutable GLArrow m_arrow;
mutable GLCurvedArrow m_curved_arrow;