ENABLE_GCODE_VIEWER -> Completed implementation of new GLModel class
This commit is contained in:
parent
8f91b4f4f4
commit
aa04f0e555
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 };
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user