mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Use Vertex Buffer Objects for rendering of 3D volumes if possible.
This commit is contained in:
		
							parent
							
								
									c32c7fa1dc
								
							
						
					
					
						commit
						7f7d2da5fe
					
				
					 8 changed files with 257 additions and 103 deletions
				
			
		| 
						 | 
				
			
			@ -174,7 +174,7 @@ void* NSGLGetProcAddress (const GLubyte *name)
 | 
			
		|||
#if defined(GLEW_REGAL)
 | 
			
		||||
#  define glewGetProcAddress(name) regalGetProcAddress((const GLchar *) name)
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
#  define glewGetProcAddress(name) ((LPCSTR)name)
 | 
			
		||||
#  define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name)
 | 
			
		||||
#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX)
 | 
			
		||||
#  define glewGetProcAddress(name) NSGLGetProcAddress(name)
 | 
			
		||||
#elif defined(__sgi) || defined(__sun) || defined(__HAIKU__)
 | 
			
		||||
| 
						 | 
				
			
			@ -12105,8 +12105,10 @@ GLenum GLEWAPIENTRY wglewInit (WGLEW_CONTEXT_ARG_DEF_LIST)
 | 
			
		|||
      extStart = (const GLubyte*)"";
 | 
			
		||||
    else
 | 
			
		||||
      extStart = (const GLubyte*)_wglewGetExtensionsStringEXT();
 | 
			
		||||
  else
 | 
			
		||||
    extStart = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC());
 | 
			
		||||
  else {
 | 
			
		||||
    HDC dc = wglGetCurrentDC(); 
 | 
			
		||||
    extStart = (const GLubyte*)_wglewGetExtensionsStringARB(dc);
 | 
			
		||||
  }
 | 
			
		||||
  extEnd = extStart + _glewStrLen(extStart);
 | 
			
		||||
  /* initialize extensions */
 | 
			
		||||
  crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1353,7 +1353,7 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
 | 
			
		|||
	return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef SLIC3R_GUI
 | 
			
		||||
#if 0
 | 
			
		||||
void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coord_t resolution, const char *path)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int w = (bbox.max.x - bbox.min.x + resolution - 1) / resolution;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ protected:
 | 
			
		|||
	std::vector<float>							m_signed_distance_field;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef SLIC3R_GUI
 | 
			
		||||
#if 0
 | 
			
		||||
// Debugging utility. Save the signed distance field.
 | 
			
		||||
extern void save_png(const Grid &grid, const BoundingBox &bbox, coord_t resolution, const char *path);
 | 
			
		||||
#endif /* SLIC3R_GUI */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -940,7 +940,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
 | 
			
		|||
                ::Slic3r::SVG svg(debug_out_path("support-bottom-contacts-simplified-%d-%d.svg", iRun, layer_id), bbox);
 | 
			
		||||
                svg.draw(union_ex(projection, false), "blue", 0.5);
 | 
			
		||||
                svg.draw(union_ex(projection_simplified, false), "red", 0.5);
 | 
			
		||||
    #ifdef SLIC3R_GUI
 | 
			
		||||
    #if 0
 | 
			
		||||
                bbox.min.x -= scale_(5.f);
 | 
			
		||||
                bbox.min.y -= scale_(5.f);
 | 
			
		||||
                bbox.max.x += scale_(5.f);
 | 
			
		||||
| 
						 | 
				
			
			@ -1593,12 +1593,12 @@ struct MyLayerExtruded
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // The source layer. It carries the height and extrusion type (bridging / non bridging, extrusion height).
 | 
			
		||||
    PrintObjectSupportMaterial::MyLayer *layer;
 | 
			
		||||
    PrintObjectSupportMaterial::MyLayer  *layer;
 | 
			
		||||
    // Collect extrusions. They will be exported sorted by the bottom height.
 | 
			
		||||
    ExtrusionEntitiesPtr                 extrusions;
 | 
			
		||||
    ExtrusionEntitiesPtr                  extrusions;
 | 
			
		||||
    // In case the extrusions are non-empty, m_polygons_to_extrude may contain the rest areas yet to be filled by additional support.
 | 
			
		||||
    // This is useful mainly for the loop interfaces, which are generated before the zig-zag infills.
 | 
			
		||||
    Polygons                            *m_polygons_to_extrude;
 | 
			
		||||
    Polygons                             *m_polygons_to_extrude;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef std::vector<MyLayerExtruded*> MyLayerExtrudedPtrs;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
#include <GL/glew.h>
 | 
			
		||||
 | 
			
		||||
#include "3DScene.hpp"
 | 
			
		||||
 | 
			
		||||
#include "../../libslic3r/libslic3r.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +23,10 @@ namespace Slic3r {
 | 
			
		|||
 | 
			
		||||
void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh)
 | 
			
		||||
{
 | 
			
		||||
    assert(triangle_indices.empty() && vertices_and_normals_interleaved_size == 0);
 | 
			
		||||
    assert(quad_indices.empty() && triangle_indices_size == 0);
 | 
			
		||||
    assert(vertices_and_normals_interleaved.size() % 6 == 0 && quad_indices_size == vertices_and_normals_interleaved.size());
 | 
			
		||||
 | 
			
		||||
    this->vertices_and_normals_interleaved.reserve(this->vertices_and_normals_interleaved.size() + 3 * 3 * 2 * mesh.facets_count());
 | 
			
		||||
    
 | 
			
		||||
    for (int i = 0; i < mesh.stl.stats.number_of_facets; ++ i) {
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +34,130 @@ void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh)
 | 
			
		|||
        for (int j = 0; j < 3; ++ j)
 | 
			
		||||
            this->push_geometry(facet.vertex[j].x, facet.vertex[j].y, facet.vertex[j].z, facet.normal.x, facet.normal.y, facet.normal.z);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vertices_and_normals_interleaved_size = this->vertices_and_normals_interleaved.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLIndexedVertexArray::finalize_geometry(bool use_VBOs)
 | 
			
		||||
{
 | 
			
		||||
    assert(this->vertices_and_normals_interleaved_VBO_id == 0);
 | 
			
		||||
    assert(this->triangle_indices_VBO_id == 0);
 | 
			
		||||
    assert(this->quad_indices_VBO_id == 0);
 | 
			
		||||
 | 
			
		||||
    this->setup_sizes();
 | 
			
		||||
 | 
			
		||||
    if (use_VBOs) {
 | 
			
		||||
        if (! empty()) {
 | 
			
		||||
            glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
            glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW);
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
			
		||||
            this->vertices_and_normals_interleaved.clear();
 | 
			
		||||
        }
 | 
			
		||||
        if (! this->triangle_indices.empty()) {
 | 
			
		||||
            glGenBuffers(1, &this->triangle_indices_VBO_id);
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
 | 
			
		||||
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW);
 | 
			
		||||
            this->triangle_indices.clear();
 | 
			
		||||
        }
 | 
			
		||||
        if (! this->quad_indices.empty()) {
 | 
			
		||||
            glGenBuffers(1, &this->quad_indices_VBO_id);
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
 | 
			
		||||
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW);
 | 
			
		||||
            this->quad_indices.clear();
 | 
			
		||||
        }
 | 
			
		||||
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 | 
			
		||||
    }
 | 
			
		||||
    this->shrink_to_fit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLIndexedVertexArray::release_geometry()
 | 
			
		||||
{
 | 
			
		||||
    if (this->vertices_and_normals_interleaved_VBO_id)
 | 
			
		||||
        glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
    if (this->triangle_indices_VBO_id)
 | 
			
		||||
        glDeleteBuffers(1, &this->triangle_indices_VBO_id);
 | 
			
		||||
    if (this->quad_indices_VBO_id)
 | 
			
		||||
        glDeleteBuffers(1, &this->quad_indices_VBO_id);
 | 
			
		||||
    this->clear();
 | 
			
		||||
    this->shrink_to_fit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLIndexedVertexArray::render() const
 | 
			
		||||
{
 | 
			
		||||
    if (this->indexed()) {
 | 
			
		||||
        if (this->vertices_and_normals_interleaved_VBO_id) {
 | 
			
		||||
            // Render using the Vertex Buffer Objects.
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
            glInterleavedArrays(GL_N3F_V3F, 0, nullptr);
 | 
			
		||||
            if (this->triangle_indices_size > 0) {
 | 
			
		||||
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
 | 
			
		||||
                glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr);
 | 
			
		||||
            }
 | 
			
		||||
            if (this->quad_indices_size > 0) {
 | 
			
		||||
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
 | 
			
		||||
                glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr);
 | 
			
		||||
            }
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Render in an immediate mode.
 | 
			
		||||
            glInterleavedArrays(GL_N3F_V3F, 0, this->vertices_and_normals_interleaved.data());
 | 
			
		||||
            // Due to issues with the Intel drivers, rather limit the amount of vertices processed per draw command.
 | 
			
		||||
            if (! this->triangle_indices.empty())
 | 
			
		||||
                glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data());
 | 
			
		||||
            if (! this->quad_indices.empty())
 | 
			
		||||
                glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data());
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if (this->vertices_and_normals_interleaved_VBO_id) {
 | 
			
		||||
            // Render using the Vertex Buffer Objects.
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
            glInterleavedArrays(GL_N3F_V3F, 0, nullptr);
 | 
			
		||||
            glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6));
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Render in an immediate mode.
 | 
			
		||||
            glInterleavedArrays(GL_N3F_V3F, 0, this->vertices_and_normals_interleaved.data());
 | 
			
		||||
            glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glInterleavedArrays(GL_N3F_V3F, 0, nullptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLIndexedVertexArray::render(
 | 
			
		||||
    const std::pair<size_t, size_t> &tverts_range,
 | 
			
		||||
    const std::pair<size_t, size_t> &qverts_range) const 
 | 
			
		||||
{
 | 
			
		||||
    assert(this->indexed());
 | 
			
		||||
    if (! this->indexed())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (this->vertices_and_normals_interleaved_VBO_id) {
 | 
			
		||||
        // Render using the Vertex Buffer Objects.
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
        glInterleavedArrays(GL_N3F_V3F, 0, nullptr);
 | 
			
		||||
        if (this->triangle_indices_size > 0) {
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
 | 
			
		||||
            glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4));
 | 
			
		||||
        }
 | 
			
		||||
        if (this->quad_indices_size > 0) {
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
 | 
			
		||||
            glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4));
 | 
			
		||||
        }
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
			
		||||
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
        // Render in an immediate mode.
 | 
			
		||||
        glInterleavedArrays(GL_N3F_V3F, 0, this->vertices_and_normals_interleaved.data());
 | 
			
		||||
        if (! this->triangle_indices.empty())
 | 
			
		||||
            glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first));
 | 
			
		||||
        if (! this->quad_indices.empty())
 | 
			
		||||
            glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glInterleavedArrays(GL_N3F_V3F, 0, nullptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLVolume::set_range(double min_z, double max_z)
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +195,18 @@ void GLVolume::set_range(double min_z, double max_z)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLVolume::render() const
 | 
			
		||||
{
 | 
			
		||||
    glCullFace(GL_BACK);
 | 
			
		||||
    glPushMatrix();
 | 
			
		||||
    glTranslated(this->origin.x, this->origin.y, this->origin.z);
 | 
			
		||||
    if (this->indexed_vertex_array.indexed())
 | 
			
		||||
        this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
 | 
			
		||||
    else
 | 
			
		||||
        this->indexed_vertex_array.render();
 | 
			
		||||
    glPopMatrix();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLVolume::generate_layer_height_texture(PrintObject *print_object, bool force)
 | 
			
		||||
{
 | 
			
		||||
    GLTexture *tex = this->layer_height_texture.get();
 | 
			
		||||
| 
						 | 
				
			
			@ -235,7 +377,6 @@ static void thick_lines_to_indexed_vertex_array(
 | 
			
		|||
            idx_a[BOTTOM] = idx_prev[BOTTOM];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool sharp = true;
 | 
			
		||||
        if (ii == 0) {
 | 
			
		||||
            // Start of the 1st line segment.
 | 
			
		||||
            idx_a[LEFT ] = idx_last ++;
 | 
			
		||||
| 
						 | 
				
			
			@ -490,6 +631,11 @@ static void extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, fl
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _3DScene::_glew_init()
 | 
			
		||||
{ 
 | 
			
		||||
    glewInit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create 3D thick extrusion lines for a skirt and brim.
 | 
			
		||||
// Adds a new Slic3r::GUI::3DScene::Volume to volumes.
 | 
			
		||||
void _3DScene::_load_print_toolpaths(
 | 
			
		||||
| 
						 | 
				
			
			@ -539,6 +685,7 @@ void _3DScene::_load_print_toolpaths(
 | 
			
		|||
    auto bb = print->bounding_box();
 | 
			
		||||
    volume.bounding_box.merge(Pointf3(unscale(bb.min.x), unscale(bb.min.y), 0.f));
 | 
			
		||||
    volume.bounding_box.merge(Pointf3(unscale(bb.max.x), unscale(bb.max.y), 0.f));
 | 
			
		||||
    volume.indexed_vertex_array.finalize_geometry(use_VBOs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create 3D thick extrusion lines for object forming extrusions.
 | 
			
		||||
| 
						 | 
				
			
			@ -559,8 +706,10 @@ void _3DScene::_load_print_object_toolpaths(
 | 
			
		|||
        bool                         has_infill;
 | 
			
		||||
        bool                         has_support;
 | 
			
		||||
 | 
			
		||||
//        static const size_t          alloc_size_max    () { return 32 * 1048576 / 4; }
 | 
			
		||||
        static const size_t          alloc_size_max    () { return 4 * 1048576 / 4; }
 | 
			
		||||
        // Number of vertices (each vertex is 6x4=24 bytes long)
 | 
			
		||||
        static const size_t          alloc_size_max    () { return 131072; } // 3.15MB
 | 
			
		||||
//        static const size_t          alloc_size_max    () { return 65536; } // 1.57MB 
 | 
			
		||||
//        static const size_t          alloc_size_max    () { return 32768; } // 786kB
 | 
			
		||||
        static const size_t          alloc_size_reserve() { return alloc_size_max() * 2; }
 | 
			
		||||
 | 
			
		||||
        static const float*          color_perimeters  () { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
 | 
			
		||||
| 
						 | 
				
			
			@ -672,6 +821,8 @@ void _3DScene::_load_print_object_toolpaths(
 | 
			
		|||
        volume_ptr += v.volumes.size();
 | 
			
		||||
        v.volumes.clear();
 | 
			
		||||
    }
 | 
			
		||||
    for (GLVolume *v : volumes->volumes)
 | 
			
		||||
        v->indexed_vertex_array.finalize_geometry(use_VBOs);
 | 
			
		||||
  
 | 
			
		||||
    BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end"; 
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,31 +17,49 @@ class ModelObject;
 | 
			
		|||
// possibly indexed by triangles and / or quads.
 | 
			
		||||
class GLIndexedVertexArray {
 | 
			
		||||
public:
 | 
			
		||||
    GLIndexedVertexArray() {}
 | 
			
		||||
    GLIndexedVertexArray() : 
 | 
			
		||||
        vertices_and_normals_interleaved_VBO_id(0),
 | 
			
		||||
        triangle_indices_VBO_id(0),
 | 
			
		||||
        quad_indices_VBO_id(0)
 | 
			
		||||
        { this->setup_sizes(); }
 | 
			
		||||
    GLIndexedVertexArray(const GLIndexedVertexArray &rhs) :
 | 
			
		||||
        vertices_and_normals_interleaved(rhs.vertices_and_normals_interleaved),
 | 
			
		||||
        triangle_indices(rhs.triangle_indices),
 | 
			
		||||
        quad_indices(rhs.quad_indices)
 | 
			
		||||
        {}
 | 
			
		||||
        quad_indices(rhs.quad_indices),
 | 
			
		||||
        vertices_and_normals_interleaved_VBO_id(0),
 | 
			
		||||
        triangle_indices_VBO_id(0),
 | 
			
		||||
        quad_indices_VBO_id(0)
 | 
			
		||||
        { this->setup_sizes(); }
 | 
			
		||||
    GLIndexedVertexArray(GLIndexedVertexArray &&rhs) :
 | 
			
		||||
        vertices_and_normals_interleaved(std::move(rhs.vertices_and_normals_interleaved)),
 | 
			
		||||
        triangle_indices(std::move(rhs.triangle_indices)),
 | 
			
		||||
        quad_indices(std::move(rhs.quad_indices))
 | 
			
		||||
        {}
 | 
			
		||||
        quad_indices(std::move(rhs.quad_indices)),
 | 
			
		||||
        vertices_and_normals_interleaved_VBO_id(0),
 | 
			
		||||
        triangle_indices_VBO_id(0),
 | 
			
		||||
        quad_indices_VBO_id(0)
 | 
			
		||||
        { this->setup_sizes(); }
 | 
			
		||||
 | 
			
		||||
    GLIndexedVertexArray& operator=(const GLIndexedVertexArray &rhs)
 | 
			
		||||
    {
 | 
			
		||||
        assert(vertices_and_normals_interleaved_VBO_id == 0);
 | 
			
		||||
        assert(triangle_indices_VBO_id == 0);
 | 
			
		||||
        assert(triangle_indices_VBO_id == 0);
 | 
			
		||||
        this->vertices_and_normals_interleaved = rhs.vertices_and_normals_interleaved;
 | 
			
		||||
        this->triangle_indices                 = rhs.triangle_indices;
 | 
			
		||||
        this->quad_indices                     = rhs.quad_indices;
 | 
			
		||||
        this->setup_sizes();
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GLIndexedVertexArray& operator=(GLIndexedVertexArray &&rhs) 
 | 
			
		||||
    {
 | 
			
		||||
        assert(vertices_and_normals_interleaved_VBO_id == 0);
 | 
			
		||||
        assert(triangle_indices_VBO_id == 0);
 | 
			
		||||
        assert(triangle_indices_VBO_id == 0);
 | 
			
		||||
        this->vertices_and_normals_interleaved = std::move(rhs.vertices_and_normals_interleaved);
 | 
			
		||||
        this->triangle_indices                 = std::move(rhs.triangle_indices);
 | 
			
		||||
        this->quad_indices                     = std::move(rhs.quad_indices);
 | 
			
		||||
        this->setup_sizes();
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -50,8 +68,22 @@ public:
 | 
			
		|||
    std::vector<int>   triangle_indices;
 | 
			
		||||
    std::vector<int>   quad_indices;
 | 
			
		||||
 | 
			
		||||
    // When the geometry data is loaded into the graphics card as Vertex Buffer Objects,
 | 
			
		||||
    // the above mentioned std::vectors are cleared and the following variables keep their original length.
 | 
			
		||||
    size_t             vertices_and_normals_interleaved_size;
 | 
			
		||||
    size_t             triangle_indices_size;
 | 
			
		||||
    size_t             quad_indices_size;
 | 
			
		||||
 | 
			
		||||
    // IDs of the Vertex Array Objects, into which the geometry has been loaded.
 | 
			
		||||
    // Zero if the VBOs are not used.
 | 
			
		||||
    unsigned int       vertices_and_normals_interleaved_VBO_id;
 | 
			
		||||
    unsigned int       triangle_indices_VBO_id;
 | 
			
		||||
    unsigned int       quad_indices_VBO_id;
 | 
			
		||||
 | 
			
		||||
    void load_mesh_flat_shading(const TriangleMesh &mesh);
 | 
			
		||||
 | 
			
		||||
    inline bool has_VBOs() const { return vertices_and_normals_interleaved_VBO_id != 0; }
 | 
			
		||||
 | 
			
		||||
    inline void reserve(size_t sz) {
 | 
			
		||||
        this->vertices_and_normals_interleaved.reserve(sz * 6);
 | 
			
		||||
        this->triangle_indices.reserve(sz * 3);
 | 
			
		||||
| 
						 | 
				
			
			@ -72,23 +104,36 @@ public:
 | 
			
		|||
        push_geometry(float(x), float(y), float(z), float(nx), float(ny), float(nz));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Finalize the initialization of the geometry & indices,
 | 
			
		||||
    // upload the geometry and indices to OpenGL VBO objects
 | 
			
		||||
    // and shrink the allocated data, possibly relasing it if it has been loaded into the VBOs.
 | 
			
		||||
    void finalize_geometry(bool use_VBOs);
 | 
			
		||||
    // Release the geometry data, release OpenGL VBOs.
 | 
			
		||||
    void release_geometry();
 | 
			
		||||
    // Render either using an immediate mode, or the VBOs.
 | 
			
		||||
    void render() const;
 | 
			
		||||
    void render(const std::pair<size_t, size_t> &tverts_range, const std::pair<size_t, size_t> &qverts_range) const;
 | 
			
		||||
 | 
			
		||||
    // Is there any geometry data stored?
 | 
			
		||||
    bool empty() const { return vertices_and_normals_interleaved.empty(); }
 | 
			
		||||
    bool empty() const { return vertices_and_normals_interleaved_size == 0; }
 | 
			
		||||
 | 
			
		||||
    // Is this object indexed, or is it just a set of triangles?
 | 
			
		||||
    bool indexed() const { return ! this->empty() && (! this->triangle_indices.empty() || ! this->quad_indices.empty()); }
 | 
			
		||||
    bool indexed() const { return ! this->empty() && this->triangle_indices_size + this->quad_indices_size > 0; }
 | 
			
		||||
 | 
			
		||||
    void clear() {
 | 
			
		||||
        this->vertices_and_normals_interleaved.clear();
 | 
			
		||||
        this->triangle_indices.clear();
 | 
			
		||||
        this->quad_indices.clear(); 
 | 
			
		||||
        this->quad_indices.clear();
 | 
			
		||||
        this->setup_sizes();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Shrink the internal storage to tighly fit the data stored.
 | 
			
		||||
    void shrink_to_fit() { 
 | 
			
		||||
        if (! this->has_VBOs())
 | 
			
		||||
            this->setup_sizes();
 | 
			
		||||
        this->vertices_and_normals_interleaved.shrink_to_fit();
 | 
			
		||||
        this->triangle_indices.shrink_to_fit();
 | 
			
		||||
        this->quad_indices.shrink_to_fit(); 
 | 
			
		||||
        this->quad_indices.shrink_to_fit();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BoundingBoxf3 bounding_box() const {
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +154,13 @@ public:
 | 
			
		|||
        }
 | 
			
		||||
        return bbox;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    inline void setup_sizes() {
 | 
			
		||||
        vertices_and_normals_interleaved_size = this->vertices_and_normals_interleaved.size();
 | 
			
		||||
        triangle_indices_size                 = this->triangle_indices.size();
 | 
			
		||||
        quad_indices_size                     = this->quad_indices.size();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class GLTexture
 | 
			
		||||
| 
						 | 
				
			
			@ -201,23 +253,8 @@ public:
 | 
			
		|||
    bool                indexed() const { return this->indexed_vertex_array.indexed(); }
 | 
			
		||||
 | 
			
		||||
    void                set_range(coordf_t low, coordf_t high);
 | 
			
		||||
 | 
			
		||||
    // Non-indexed interleaved vertices & normals, likely forming triangles.
 | 
			
		||||
    void*               triangles_to_render_ptr() { return indexed_vertex_array.vertices_and_normals_interleaved.data(); }
 | 
			
		||||
    size_t              triangles_to_render_cnt() { return indexed_vertex_array.vertices_and_normals_interleaved.size() / (3 * 2); }
 | 
			
		||||
    // Indexed triangles & quads, complete set for storing into a vertex buffer.
 | 
			
		||||
    size_t              geometry_size() const { return indexed_vertex_array.vertices_and_normals_interleaved.size() * 4; }
 | 
			
		||||
    void*               triangle_indices_ptr() { return indexed_vertex_array.triangle_indices.data(); }
 | 
			
		||||
    void*               quad_indices_ptr() { return indexed_vertex_array.quad_indices.data(); }
 | 
			
		||||
    size_t              indexed_triangles_cnt() { return indexed_vertex_array.triangle_indices.size(); }
 | 
			
		||||
    size_t              indexed_quads_cnt() { return indexed_vertex_array.quad_indices.size(); }
 | 
			
		||||
    // Indexed triangles & quads, to be painted in an immediate mode.
 | 
			
		||||
    size_t              triangle_indices_to_render_offset() const { return tverts_range.first; }
 | 
			
		||||
    size_t              quad_indices_to_render_offset() const { return qverts_range.first; }
 | 
			
		||||
    size_t              indexed_triangles_to_render_cnt() const { return std::min(indexed_vertex_array.triangle_indices.size(), tverts_range.second - tverts_range.first); }
 | 
			
		||||
    size_t              indexed_quads_to_render_cnt() const { return std::min(indexed_vertex_array.quad_indices.size(), qverts_range.second - qverts_range.first); }
 | 
			
		||||
 | 
			
		||||
    void                render_VBOs() const;
 | 
			
		||||
    void                render() const;
 | 
			
		||||
    void                release_geometry() { this->indexed_vertex_array.release_geometry(); }
 | 
			
		||||
 | 
			
		||||
    /************************************************ Layer height texture ****************************************************/
 | 
			
		||||
    std::shared_ptr<GLTexture>  layer_height_texture;
 | 
			
		||||
| 
						 | 
				
			
			@ -261,10 +298,14 @@ public:
 | 
			
		|||
        const std::string       &select_by,
 | 
			
		||||
        const std::string       &drag_by);
 | 
			
		||||
 | 
			
		||||
    // Release the geometry data assigned to the volumes.
 | 
			
		||||
    // If OpenGL VBOs were allocated, an OpenGL context has to be active to release them.
 | 
			
		||||
    void release_geometry() { for (auto *v : volumes) v->release_geometry(); }
 | 
			
		||||
    // Clear the geometry
 | 
			
		||||
    void clear() { for (auto *v : volumes) delete v; volumes.clear(); }
 | 
			
		||||
 | 
			
		||||
    bool empty() const { return volumes.empty(); }
 | 
			
		||||
    void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); }
 | 
			
		||||
    void render_VBOs() const { for (GLVolume *vol : this->volumes) vol->render_VBOs(); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    GLVolumeCollection(const GLVolumeCollection &other);
 | 
			
		||||
| 
						 | 
				
			
			@ -274,6 +315,8 @@ private:
 | 
			
		|||
class _3DScene
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    static void _glew_init();
 | 
			
		||||
 | 
			
		||||
    static void _load_print_toolpaths(
 | 
			
		||||
        const Print         *print,
 | 
			
		||||
        GLVolumeCollection  *volumes,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,17 +38,7 @@
 | 
			
		|||
    bool                empty() const;
 | 
			
		||||
    bool                indexed() const;
 | 
			
		||||
 | 
			
		||||
    void*               triangles_to_render_ptr();
 | 
			
		||||
    size_t              triangles_to_render_cnt();
 | 
			
		||||
    size_t              geometry_size() const;
 | 
			
		||||
    void*               triangle_indices_ptr();
 | 
			
		||||
    void*               quad_indices_ptr();
 | 
			
		||||
    size_t              indexed_triangles_cnt();
 | 
			
		||||
    size_t              indexed_quads_cnt();
 | 
			
		||||
    size_t              triangle_indices_to_render_offset() const;
 | 
			
		||||
    size_t              quad_indices_to_render_offset() const;
 | 
			
		||||
    size_t              indexed_triangles_to_render_cnt() const;
 | 
			
		||||
    size_t              indexed_quads_to_render_cnt() const;
 | 
			
		||||
    void                render() const;
 | 
			
		||||
 | 
			
		||||
    bool                has_layer_height_texture();
 | 
			
		||||
    int                 layer_height_texture_width();
 | 
			
		||||
| 
						 | 
				
			
			@ -72,8 +62,10 @@
 | 
			
		|||
 | 
			
		||||
    int count()
 | 
			
		||||
        %code{% RETVAL = THIS->volumes.size(); %};
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    void set_range(double low, double high);
 | 
			
		||||
 | 
			
		||||
    void release_geometry();    
 | 
			
		||||
%{
 | 
			
		||||
 | 
			
		||||
SV*
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +87,12 @@ GLVolumeCollection::arrayref()
 | 
			
		|||
%package{Slic3r::GUI::_3DScene};
 | 
			
		||||
%{
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_glew_init()
 | 
			
		||||
    CODE:
 | 
			
		||||
        _3DScene::_glew_init();
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_load_print_toolpaths(print, volumes, use_VBOs)
 | 
			
		||||
        Print               *print;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue