2015-01-17 23:36:21 +00:00
|
|
|
#ifndef slic3r_3DScene_hpp_
|
|
|
|
#define slic3r_3DScene_hpp_
|
|
|
|
|
2015-12-07 23:39:54 +00:00
|
|
|
#include "../../libslic3r/libslic3r.h"
|
2015-12-06 11:54:01 +00:00
|
|
|
#include "../../libslic3r/Point.hpp"
|
|
|
|
#include "../../libslic3r/Line.hpp"
|
|
|
|
#include "../../libslic3r/TriangleMesh.hpp"
|
2017-03-28 15:09:57 +00:00
|
|
|
#include "../../libslic3r/Utils.hpp"
|
2018-07-18 12:26:42 +00:00
|
|
|
#include "../../libslic3r/Model.hpp"
|
2018-05-09 08:47:04 +00:00
|
|
|
#include "../../slic3r/GUI/GLCanvas3DManager.hpp"
|
2015-01-17 23:36:21 +00:00
|
|
|
|
2018-01-16 13:59:06 +00:00
|
|
|
class wxBitmap;
|
2018-05-09 08:47:04 +00:00
|
|
|
class wxWindow;
|
2018-01-16 13:59:06 +00:00
|
|
|
|
2015-01-17 23:36:21 +00:00
|
|
|
namespace Slic3r {
|
|
|
|
|
2017-03-13 15:02:17 +00:00
|
|
|
class Print;
|
|
|
|
class PrintObject;
|
|
|
|
class Model;
|
|
|
|
class ModelObject;
|
2018-02-14 19:35:59 +00:00
|
|
|
class GCodePreviewData;
|
2018-03-09 09:40:42 +00:00
|
|
|
class DynamicPrintConfig;
|
2018-06-05 08:56:55 +00:00
|
|
|
class ExtrusionPath;
|
|
|
|
class ExtrusionMultiPath;
|
|
|
|
class ExtrusionLoop;
|
|
|
|
class ExtrusionEntity;
|
|
|
|
class ExtrusionEntityCollection;
|
2017-03-13 15:02:17 +00:00
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
// A container for interleaved arrays of 3D vertices and normals,
|
|
|
|
// possibly indexed by triangles and / or quads.
|
|
|
|
class GLIndexedVertexArray {
|
2017-03-13 15:02:17 +00:00
|
|
|
public:
|
2017-03-16 13:02:28 +00:00
|
|
|
GLIndexedVertexArray() :
|
|
|
|
vertices_and_normals_interleaved_VBO_id(0),
|
|
|
|
triangle_indices_VBO_id(0),
|
|
|
|
quad_indices_VBO_id(0)
|
|
|
|
{ this->setup_sizes(); }
|
2017-03-15 19:45:03 +00:00
|
|
|
GLIndexedVertexArray(const GLIndexedVertexArray &rhs) :
|
|
|
|
vertices_and_normals_interleaved(rhs.vertices_and_normals_interleaved),
|
|
|
|
triangle_indices(rhs.triangle_indices),
|
2017-03-16 13:02:28 +00:00
|
|
|
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(); }
|
2017-03-15 19:45:03 +00:00
|
|
|
GLIndexedVertexArray(GLIndexedVertexArray &&rhs) :
|
|
|
|
vertices_and_normals_interleaved(std::move(rhs.vertices_and_normals_interleaved)),
|
|
|
|
triangle_indices(std::move(rhs.triangle_indices)),
|
2017-03-16 13:02:28 +00:00
|
|
|
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(); }
|
2017-03-15 19:45:03 +00:00
|
|
|
|
|
|
|
GLIndexedVertexArray& operator=(const GLIndexedVertexArray &rhs)
|
|
|
|
{
|
2017-03-16 13:02:28 +00:00
|
|
|
assert(vertices_and_normals_interleaved_VBO_id == 0);
|
|
|
|
assert(triangle_indices_VBO_id == 0);
|
|
|
|
assert(triangle_indices_VBO_id == 0);
|
2017-03-15 19:45:03 +00:00
|
|
|
this->vertices_and_normals_interleaved = rhs.vertices_and_normals_interleaved;
|
|
|
|
this->triangle_indices = rhs.triangle_indices;
|
|
|
|
this->quad_indices = rhs.quad_indices;
|
2017-03-16 13:02:28 +00:00
|
|
|
this->setup_sizes();
|
2017-03-15 19:45:03 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
GLIndexedVertexArray& operator=(GLIndexedVertexArray &&rhs)
|
|
|
|
{
|
2017-03-16 13:02:28 +00:00
|
|
|
assert(vertices_and_normals_interleaved_VBO_id == 0);
|
|
|
|
assert(triangle_indices_VBO_id == 0);
|
|
|
|
assert(triangle_indices_VBO_id == 0);
|
2017-03-15 19:45:03 +00:00
|
|
|
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);
|
2017-03-16 13:02:28 +00:00
|
|
|
this->setup_sizes();
|
2017-03-15 19:45:03 +00:00
|
|
|
return *this;
|
|
|
|
}
|
2017-03-15 15:33:25 +00:00
|
|
|
|
|
|
|
// Vertices and their normals, interleaved to be used by void glInterleavedArrays(GL_N3F_V3F, 0, x)
|
|
|
|
std::vector<float> vertices_and_normals_interleaved;
|
|
|
|
std::vector<int> triangle_indices;
|
|
|
|
std::vector<int> quad_indices;
|
|
|
|
|
2017-03-16 13:02:28 +00:00
|
|
|
// 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;
|
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
void load_mesh_flat_shading(const TriangleMesh &mesh);
|
2018-03-09 09:40:42 +00:00
|
|
|
void load_mesh_full_shading(const TriangleMesh &mesh);
|
2017-03-15 15:33:25 +00:00
|
|
|
|
2017-03-16 13:02:28 +00:00
|
|
|
inline bool has_VBOs() const { return vertices_and_normals_interleaved_VBO_id != 0; }
|
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
inline void reserve(size_t sz) {
|
|
|
|
this->vertices_and_normals_interleaved.reserve(sz * 6);
|
|
|
|
this->triangle_indices.reserve(sz * 3);
|
|
|
|
this->quad_indices.reserve(sz * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void push_geometry(float x, float y, float z, float nx, float ny, float nz) {
|
2017-03-28 15:09:57 +00:00
|
|
|
if (this->vertices_and_normals_interleaved.size() + 6 > this->vertices_and_normals_interleaved.capacity())
|
|
|
|
this->vertices_and_normals_interleaved.reserve(next_highest_power_of_2(this->vertices_and_normals_interleaved.size() + 6));
|
2017-03-15 15:33:25 +00:00
|
|
|
this->vertices_and_normals_interleaved.push_back(nx);
|
|
|
|
this->vertices_and_normals_interleaved.push_back(ny);
|
|
|
|
this->vertices_and_normals_interleaved.push_back(nz);
|
|
|
|
this->vertices_and_normals_interleaved.push_back(x);
|
|
|
|
this->vertices_and_normals_interleaved.push_back(y);
|
|
|
|
this->vertices_and_normals_interleaved.push_back(z);
|
2015-01-24 22:35:29 +00:00
|
|
|
};
|
2017-03-13 15:02:17 +00:00
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
inline void push_geometry(double x, double y, double z, double nx, double ny, double nz) {
|
|
|
|
push_geometry(float(x), float(y), float(z), float(nx), float(ny), float(nz));
|
|
|
|
}
|
|
|
|
|
2018-01-08 12:44:10 +00:00
|
|
|
inline void push_geometry(const Pointf3& p, const Vectorf3& n) {
|
2018-08-14 16:33:26 +00:00
|
|
|
push_geometry(p.x(), p.y(), p.z(), n.x(), n.y(), n.z());
|
2018-01-08 12:44:10 +00:00
|
|
|
}
|
|
|
|
|
2017-03-28 15:09:57 +00:00
|
|
|
inline void push_triangle(int idx1, int idx2, int idx3) {
|
|
|
|
if (this->triangle_indices.size() + 3 > this->vertices_and_normals_interleaved.capacity())
|
|
|
|
this->triangle_indices.reserve(next_highest_power_of_2(this->triangle_indices.size() + 3));
|
|
|
|
this->triangle_indices.push_back(idx1);
|
|
|
|
this->triangle_indices.push_back(idx2);
|
|
|
|
this->triangle_indices.push_back(idx3);
|
|
|
|
};
|
|
|
|
|
|
|
|
inline void push_quad(int idx1, int idx2, int idx3, int idx4) {
|
|
|
|
if (this->quad_indices.size() + 4 > this->vertices_and_normals_interleaved.capacity())
|
|
|
|
this->quad_indices.reserve(next_highest_power_of_2(this->quad_indices.size() + 4));
|
|
|
|
this->quad_indices.push_back(idx1);
|
|
|
|
this->quad_indices.push_back(idx2);
|
|
|
|
this->quad_indices.push_back(idx3);
|
|
|
|
this->quad_indices.push_back(idx4);
|
|
|
|
};
|
|
|
|
|
2017-03-16 13:02:28 +00:00
|
|
|
// 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;
|
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
// Is there any geometry data stored?
|
2017-03-16 13:02:28 +00:00
|
|
|
bool empty() const { return vertices_and_normals_interleaved_size == 0; }
|
2017-03-15 15:33:25 +00:00
|
|
|
|
|
|
|
// Is this object indexed, or is it just a set of triangles?
|
2017-03-16 13:02:28 +00:00
|
|
|
bool indexed() const { return ! this->empty() && this->triangle_indices_size + this->quad_indices_size > 0; }
|
2017-03-15 15:33:25 +00:00
|
|
|
|
2017-03-15 19:45:03 +00:00
|
|
|
void clear() {
|
|
|
|
this->vertices_and_normals_interleaved.clear();
|
|
|
|
this->triangle_indices.clear();
|
2017-03-16 13:02:28 +00:00
|
|
|
this->quad_indices.clear();
|
|
|
|
this->setup_sizes();
|
2017-03-15 19:45:03 +00:00
|
|
|
}
|
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
// Shrink the internal storage to tighly fit the data stored.
|
|
|
|
void shrink_to_fit() {
|
2017-03-16 13:02:28 +00:00
|
|
|
if (! this->has_VBOs())
|
|
|
|
this->setup_sizes();
|
2017-03-15 15:33:25 +00:00
|
|
|
this->vertices_and_normals_interleaved.shrink_to_fit();
|
|
|
|
this->triangle_indices.shrink_to_fit();
|
2017-03-16 13:02:28 +00:00
|
|
|
this->quad_indices.shrink_to_fit();
|
2017-03-15 15:33:25 +00:00
|
|
|
}
|
2017-03-13 15:02:17 +00:00
|
|
|
|
|
|
|
BoundingBoxf3 bounding_box() const {
|
|
|
|
BoundingBoxf3 bbox;
|
2017-03-15 15:33:25 +00:00
|
|
|
if (! this->vertices_and_normals_interleaved.empty()) {
|
2017-09-12 16:20:06 +00:00
|
|
|
bbox.defined = true;
|
2018-08-14 16:33:26 +00:00
|
|
|
bbox.min.x() = bbox.max.x() = this->vertices_and_normals_interleaved[3];
|
|
|
|
bbox.min.y() = bbox.max.y() = this->vertices_and_normals_interleaved[4];
|
|
|
|
bbox.min.z() = bbox.max.z() = this->vertices_and_normals_interleaved[5];
|
2017-03-15 15:33:25 +00:00
|
|
|
for (size_t i = 9; i < this->vertices_and_normals_interleaved.size(); i += 6) {
|
|
|
|
const float *verts = this->vertices_and_normals_interleaved.data() + i;
|
2018-08-14 16:33:26 +00:00
|
|
|
bbox.min.x() = std::min<coordf_t>(bbox.min.x(), verts[0]);
|
|
|
|
bbox.min.y() = std::min<coordf_t>(bbox.min.y(), verts[1]);
|
|
|
|
bbox.min.z() = std::min<coordf_t>(bbox.min.z(), verts[2]);
|
|
|
|
bbox.max.x() = std::max<coordf_t>(bbox.max.x(), verts[0]);
|
|
|
|
bbox.max.y() = std::max<coordf_t>(bbox.max.y(), verts[1]);
|
|
|
|
bbox.max.z() = std::max<coordf_t>(bbox.max.z(), verts[2]);
|
2017-03-13 15:02:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return bbox;
|
|
|
|
}
|
2017-03-16 13:02:28 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2017-03-13 15:02:17 +00:00
|
|
|
};
|
|
|
|
|
2018-07-18 13:07:52 +00:00
|
|
|
class LayersTexture
|
2017-03-13 15:02:17 +00:00
|
|
|
{
|
|
|
|
public:
|
2018-07-18 13:07:52 +00:00
|
|
|
LayersTexture() : width(0), height(0), levels(0), cells(0) {}
|
2017-03-13 15:02:17 +00:00
|
|
|
|
|
|
|
// Texture data
|
|
|
|
std::vector<char> data;
|
|
|
|
// Width of the texture, top level.
|
|
|
|
size_t width;
|
|
|
|
// Height of the texture, top level.
|
|
|
|
size_t height;
|
|
|
|
// For how many levels of detail is the data allocated?
|
|
|
|
size_t levels;
|
|
|
|
// Number of texture cells allocated for the height texture.
|
|
|
|
size_t cells;
|
|
|
|
};
|
|
|
|
|
|
|
|
class GLVolume {
|
2018-03-09 13:33:44 +00:00
|
|
|
struct LayerHeightTextureData
|
|
|
|
{
|
|
|
|
// ID of the layer height texture
|
|
|
|
unsigned int texture_id;
|
|
|
|
// ID of the shader used to render with the layer height texture
|
|
|
|
unsigned int shader_id;
|
|
|
|
// The print object to update when generating the layer height texture
|
|
|
|
PrintObject* print_object;
|
|
|
|
|
|
|
|
float z_cursor_relative;
|
|
|
|
float edit_band_width;
|
|
|
|
|
|
|
|
LayerHeightTextureData() { reset(); }
|
|
|
|
|
|
|
|
void reset()
|
|
|
|
{
|
|
|
|
texture_id = 0;
|
|
|
|
shader_id = 0;
|
|
|
|
print_object = nullptr;
|
|
|
|
z_cursor_relative = 0.0f;
|
|
|
|
edit_band_width = 0.0f;
|
|
|
|
}
|
|
|
|
|
2018-06-21 06:37:04 +00:00
|
|
|
bool can_use() const { return (texture_id > 0) && (shader_id > 0) && (print_object != nullptr); }
|
2018-03-09 13:33:44 +00:00
|
|
|
};
|
|
|
|
|
2017-03-13 15:02:17 +00:00
|
|
|
public:
|
2018-03-09 09:40:42 +00:00
|
|
|
static const float SELECTED_COLOR[4];
|
|
|
|
static const float HOVER_COLOR[4];
|
|
|
|
static const float OUTSIDE_COLOR[4];
|
|
|
|
static const float SELECTED_OUTSIDE_COLOR[4];
|
|
|
|
|
2018-06-21 06:37:04 +00:00
|
|
|
GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f);
|
2017-03-13 15:02:17 +00:00
|
|
|
GLVolume(const float *rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {}
|
|
|
|
|
2018-06-21 06:37:04 +00:00
|
|
|
private:
|
|
|
|
// Offset of the volume to be rendered.
|
|
|
|
Pointf3 m_origin;
|
|
|
|
// Rotation around Z axis of the volume to be rendered.
|
|
|
|
float m_angle_z;
|
|
|
|
// Scale factor of the volume to be rendered.
|
|
|
|
float m_scale_factor;
|
|
|
|
// World matrix of the volume to be rendered.
|
2018-08-14 19:33:41 +00:00
|
|
|
mutable Transform3f m_world_mat;
|
2018-06-21 06:37:04 +00:00
|
|
|
// Bounding box of this volume, in unscaled coordinates.
|
|
|
|
mutable BoundingBoxf3 m_transformed_bounding_box;
|
|
|
|
// Whether or not is needed to recalculate the world matrix.
|
|
|
|
mutable bool m_dirty;
|
2017-03-13 15:02:17 +00:00
|
|
|
|
2018-06-21 06:37:04 +00:00
|
|
|
public:
|
2017-05-17 14:53:40 +00:00
|
|
|
|
2017-03-13 15:02:17 +00:00
|
|
|
// Bounding box of this volume, in unscaled coordinates.
|
|
|
|
BoundingBoxf3 bounding_box;
|
|
|
|
// Color of the triangles / quads held by this volume.
|
|
|
|
float color[4];
|
2018-03-09 09:40:42 +00:00
|
|
|
// Color used to render this volume.
|
|
|
|
float render_color[4];
|
2017-03-13 15:02:17 +00:00
|
|
|
// An ID containing the object ID, volume ID and instance ID.
|
|
|
|
int composite_id;
|
|
|
|
// An ID for group selection. It may be the same for all meshes of all object instances, or for just a single object instance.
|
|
|
|
int select_group_id;
|
|
|
|
// An ID for group dragging. It may be the same for all meshes of all object instances, or for just a single object instance.
|
|
|
|
int drag_group_id;
|
2018-04-05 10:52:29 +00:00
|
|
|
// An ID containing the extruder ID (used to select color).
|
|
|
|
int extruder_id;
|
2017-03-13 15:02:17 +00:00
|
|
|
// Is this object selected?
|
|
|
|
bool selected;
|
2018-01-11 13:09:54 +00:00
|
|
|
// Whether or not this volume is active for rendering
|
2018-01-17 09:39:05 +00:00
|
|
|
bool is_active;
|
2018-02-19 10:28:56 +00:00
|
|
|
// Whether or not to use this volume when applying zoom_to_volumes()
|
|
|
|
bool zoom_to_volumes;
|
2018-03-09 09:40:42 +00:00
|
|
|
// Wheter or not this volume is enabled for outside print volume detection.
|
|
|
|
bool outside_printer_detection_enabled;
|
|
|
|
// Wheter or not this volume is outside print volume.
|
|
|
|
bool is_outside;
|
2017-03-13 15:02:17 +00:00
|
|
|
// Boolean: Is mouse over this object?
|
|
|
|
bool hover;
|
2018-04-05 10:52:29 +00:00
|
|
|
// Wheter or not this volume has been generated from a modifier
|
2018-06-18 13:07:17 +00:00
|
|
|
bool is_modifier;
|
2018-04-05 10:52:29 +00:00
|
|
|
// Wheter or not this volume has been generated from the wipe tower
|
2018-06-18 13:07:17 +00:00
|
|
|
bool is_wipe_tower;
|
2017-03-13 15:02:17 +00:00
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
// Interleaved triangles & normals with indexed triangles & quads.
|
|
|
|
GLIndexedVertexArray indexed_vertex_array;
|
|
|
|
// Ranges of triangle and quad indices to be rendered.
|
2017-03-13 15:02:17 +00:00
|
|
|
std::pair<size_t, size_t> tverts_range;
|
2017-03-15 15:33:25 +00:00
|
|
|
std::pair<size_t, size_t> qverts_range;
|
|
|
|
|
2017-03-13 15:02:17 +00:00
|
|
|
// If the qverts or tverts contain thick extrusions, then offsets keeps pointers of the starts
|
|
|
|
// of the extrusions per layer.
|
|
|
|
std::vector<coordf_t> print_zs;
|
2017-03-14 09:11:08 +00:00
|
|
|
// Offset into qverts & tverts, or offsets into indices stored into an OpenGL name_index_buffer.
|
2017-03-13 15:02:17 +00:00
|
|
|
std::vector<size_t> offsets;
|
|
|
|
|
2018-03-09 09:40:42 +00:00
|
|
|
void set_render_color(float r, float g, float b, float a);
|
|
|
|
void set_render_color(const float* rgba, unsigned int size);
|
|
|
|
// Sets render color in dependence of current state
|
|
|
|
void set_render_color();
|
2018-01-11 13:09:54 +00:00
|
|
|
|
2018-06-21 06:37:04 +00:00
|
|
|
const Pointf3& get_origin() const;
|
|
|
|
void set_origin(const Pointf3& origin);
|
|
|
|
void set_angle_z(float angle_z);
|
|
|
|
void set_scale_factor(float scale_factor);
|
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
int object_idx() const { return this->composite_id / 1000000; }
|
|
|
|
int volume_idx() const { return (this->composite_id / 1000) % 1000; }
|
|
|
|
int instance_idx() const { return this->composite_id % 1000; }
|
2018-06-21 06:37:04 +00:00
|
|
|
|
2018-08-14 19:33:41 +00:00
|
|
|
const Transform3f& world_matrix() const;
|
2018-06-21 06:37:04 +00:00
|
|
|
BoundingBoxf3 transformed_bounding_box() const;
|
2017-03-13 15:02:17 +00:00
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
bool empty() const { return this->indexed_vertex_array.empty(); }
|
|
|
|
bool indexed() const { return this->indexed_vertex_array.indexed(); }
|
|
|
|
|
|
|
|
void set_range(coordf_t low, coordf_t high);
|
2017-03-16 13:02:28 +00:00
|
|
|
void render() const;
|
2018-03-09 13:33:44 +00:00
|
|
|
void render_using_layer_height() const;
|
2018-06-21 06:37:04 +00:00
|
|
|
void render_VBOs(int color_id, int detection_id, int worldmatrix_id) const;
|
|
|
|
void render_legacy() const;
|
|
|
|
|
2017-03-30 08:25:52 +00:00
|
|
|
void finalize_geometry(bool use_VBOs) { this->indexed_vertex_array.finalize_geometry(use_VBOs); }
|
2017-03-16 13:02:28 +00:00
|
|
|
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
|
2017-03-14 09:11:08 +00:00
|
|
|
|
2017-03-15 15:33:25 +00:00
|
|
|
/************************************************ Layer height texture ****************************************************/
|
2018-07-18 13:07:52 +00:00
|
|
|
std::shared_ptr<LayersTexture> layer_height_texture;
|
2018-03-09 13:33:44 +00:00
|
|
|
// Data to render this volume using the layer height texture
|
|
|
|
LayerHeightTextureData layer_height_texture_data;
|
2017-03-13 15:02:17 +00:00
|
|
|
|
|
|
|
bool has_layer_height_texture() const
|
|
|
|
{ return this->layer_height_texture.get() != nullptr; }
|
|
|
|
size_t layer_height_texture_width() const
|
|
|
|
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->width; }
|
|
|
|
size_t layer_height_texture_height() const
|
|
|
|
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->height; }
|
|
|
|
size_t layer_height_texture_cells() const
|
|
|
|
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->cells; }
|
2018-03-09 13:33:44 +00:00
|
|
|
void* layer_height_texture_data_ptr_level0() const {
|
2017-03-13 15:02:17 +00:00
|
|
|
return (layer_height_texture.get() == nullptr) ? 0 :
|
|
|
|
(void*)layer_height_texture->data.data();
|
|
|
|
}
|
2018-03-09 13:33:44 +00:00
|
|
|
void* layer_height_texture_data_ptr_level1() const {
|
2017-03-13 15:02:17 +00:00
|
|
|
return (layer_height_texture.get() == nullptr) ? 0 :
|
|
|
|
(void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4);
|
|
|
|
}
|
2018-04-13 07:01:48 +00:00
|
|
|
double layer_height_texture_z_to_row_id() const;
|
2017-03-13 15:02:17 +00:00
|
|
|
void generate_layer_height_texture(PrintObject *print_object, bool force);
|
|
|
|
|
2018-03-09 13:33:44 +00:00
|
|
|
void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, PrintObject* print_object, float z_cursor_relative, float edit_band_width)
|
2018-02-12 08:04:05 +00:00
|
|
|
{
|
2018-03-09 13:33:44 +00:00
|
|
|
layer_height_texture_data.texture_id = texture_id;
|
|
|
|
layer_height_texture_data.shader_id = shader_id;
|
|
|
|
layer_height_texture_data.print_object = print_object;
|
|
|
|
layer_height_texture_data.z_cursor_relative = z_cursor_relative;
|
|
|
|
layer_height_texture_data.edit_band_width = edit_band_width;
|
|
|
|
}
|
2018-02-12 08:04:05 +00:00
|
|
|
|
2018-03-09 13:33:44 +00:00
|
|
|
void reset_layer_height_texture_data() { layer_height_texture_data.reset(); }
|
2017-03-13 15:02:17 +00:00
|
|
|
};
|
2018-02-12 08:04:05 +00:00
|
|
|
|
2017-03-13 15:02:17 +00:00
|
|
|
class GLVolumeCollection
|
|
|
|
{
|
2018-03-09 09:40:42 +00:00
|
|
|
// min and max vertex of the print box volume
|
|
|
|
float print_box_min[3];
|
|
|
|
float print_box_max[3];
|
2018-02-12 08:04:05 +00:00
|
|
|
|
2017-03-13 15:02:17 +00:00
|
|
|
public:
|
|
|
|
std::vector<GLVolume*> volumes;
|
|
|
|
|
|
|
|
GLVolumeCollection() {};
|
|
|
|
~GLVolumeCollection() { clear(); };
|
|
|
|
|
|
|
|
std::vector<int> load_object(
|
|
|
|
const ModelObject *model_object,
|
|
|
|
int obj_idx,
|
|
|
|
const std::vector<int> &instance_idxs,
|
|
|
|
const std::string &color_by,
|
|
|
|
const std::string &select_by,
|
2017-03-20 11:05:20 +00:00
|
|
|
const std::string &drag_by,
|
|
|
|
bool use_VBOs);
|
2017-03-13 15:02:17 +00:00
|
|
|
|
2017-05-17 14:53:40 +00:00
|
|
|
int load_wipe_tower_preview(
|
2017-11-30 13:43:47 +00:00
|
|
|
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs);
|
2017-05-17 14:53:40 +00:00
|
|
|
|
2017-03-20 11:05:20 +00:00
|
|
|
// Render the volumes by OpenGL.
|
|
|
|
void render_VBOs() const;
|
|
|
|
void render_legacy() const;
|
2017-03-30 08:25:52 +00:00
|
|
|
|
|
|
|
// 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) { for (auto *v : volumes) v->finalize_geometry(use_VBOs); }
|
2017-03-16 13:02:28 +00:00
|
|
|
// 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
|
2017-03-13 15:02:17 +00:00
|
|
|
void clear() { for (auto *v : volumes) delete v; volumes.clear(); }
|
2017-03-16 13:02:28 +00:00
|
|
|
|
2017-03-13 15:02:17 +00:00
|
|
|
bool empty() const { return volumes.empty(); }
|
|
|
|
void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); }
|
2017-03-15 19:45:03 +00:00
|
|
|
|
2018-03-09 09:40:42 +00:00
|
|
|
void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) {
|
|
|
|
print_box_min[0] = min_x; print_box_min[1] = min_y; print_box_min[2] = min_z;
|
|
|
|
print_box_max[0] = max_x; print_box_max[1] = max_y; print_box_max[2] = max_z;
|
|
|
|
}
|
|
|
|
|
2018-07-18 12:26:42 +00:00
|
|
|
// returns true if all the volumes are completely contained in the print volume
|
|
|
|
// returns the containment state in the given out_state, if non-null
|
|
|
|
bool check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state);
|
2018-04-24 07:00:33 +00:00
|
|
|
void reset_outside_state();
|
|
|
|
|
2018-04-05 10:52:29 +00:00
|
|
|
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
2018-02-12 08:04:05 +00:00
|
|
|
|
2018-02-22 07:59:47 +00:00
|
|
|
// Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection
|
2018-05-18 08:14:47 +00:00
|
|
|
std::vector<double> get_current_print_zs(bool active_only) const;
|
2018-02-22 07:59:47 +00:00
|
|
|
|
2017-03-15 19:45:03 +00:00
|
|
|
private:
|
|
|
|
GLVolumeCollection(const GLVolumeCollection &other);
|
|
|
|
GLVolumeCollection& operator=(const GLVolumeCollection &);
|
2015-01-24 22:35:29 +00:00
|
|
|
};
|
|
|
|
|
2015-01-17 23:36:21 +00:00
|
|
|
class _3DScene
|
|
|
|
{
|
2018-05-09 08:47:04 +00:00
|
|
|
static GUI::GLCanvas3DManager s_canvas_mgr;
|
2018-02-06 11:43:25 +00:00
|
|
|
|
2017-03-13 15:02:17 +00:00
|
|
|
public:
|
2018-05-09 08:47:04 +00:00
|
|
|
static void init_gl();
|
2018-06-04 08:14:09 +00:00
|
|
|
static std::string get_gl_info(bool format_as_html, bool extensions);
|
2018-05-09 08:47:04 +00:00
|
|
|
static bool use_VBOs();
|
|
|
|
|
2018-06-11 13:49:04 +00:00
|
|
|
static bool add_canvas(wxGLCanvas* canvas);
|
2018-05-09 08:47:04 +00:00
|
|
|
static bool remove_canvas(wxGLCanvas* canvas);
|
|
|
|
static void remove_all_canvases();
|
|
|
|
|
2018-06-04 11:15:28 +00:00
|
|
|
static bool init(wxGLCanvas* canvas);
|
2018-05-09 08:47:04 +00:00
|
|
|
|
2018-06-22 14:06:37 +00:00
|
|
|
static void set_as_dirty(wxGLCanvas* canvas);
|
2018-05-09 08:47:04 +00:00
|
|
|
|
2018-06-11 11:48:02 +00:00
|
|
|
static unsigned int get_volumes_count(wxGLCanvas* canvas);
|
2018-05-18 12:08:59 +00:00
|
|
|
static void reset_volumes(wxGLCanvas* canvas);
|
2018-05-25 07:03:55 +00:00
|
|
|
static void deselect_volumes(wxGLCanvas* canvas);
|
|
|
|
static void select_volume(wxGLCanvas* canvas, unsigned int id);
|
2018-06-08 07:40:00 +00:00
|
|
|
static void update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections);
|
2018-06-11 11:48:02 +00:00
|
|
|
static bool check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config);
|
|
|
|
static bool move_volume_up(wxGLCanvas* canvas, unsigned int id);
|
|
|
|
static bool move_volume_down(wxGLCanvas* canvas, unsigned int id);
|
2018-06-08 07:40:00 +00:00
|
|
|
|
|
|
|
static void set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections);
|
2018-05-18 12:08:59 +00:00
|
|
|
|
2018-05-23 09:14:49 +00:00
|
|
|
static void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config);
|
2018-05-28 13:23:01 +00:00
|
|
|
static void set_print(wxGLCanvas* canvas, Print* print);
|
2018-06-07 09:18:28 +00:00
|
|
|
static void set_model(wxGLCanvas* canvas, Model* model);
|
2018-05-23 09:14:49 +00:00
|
|
|
|
2018-05-14 12:14:19 +00:00
|
|
|
static void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape);
|
2018-05-15 13:38:25 +00:00
|
|
|
static void set_auto_bed_shape(wxGLCanvas* canvas);
|
2018-05-14 12:14:19 +00:00
|
|
|
|
2018-05-15 08:32:38 +00:00
|
|
|
static BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas);
|
2018-05-18 11:02:47 +00:00
|
|
|
|
|
|
|
static void set_axes_length(wxGLCanvas* canvas, float length);
|
|
|
|
|
2018-05-18 09:05:48 +00:00
|
|
|
static void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons);
|
|
|
|
|
2018-06-06 10:36:52 +00:00
|
|
|
static void set_color_by(wxGLCanvas* canvas, const std::string& value);
|
|
|
|
static void set_select_by(wxGLCanvas* canvas, const std::string& value);
|
|
|
|
static void set_drag_by(wxGLCanvas* canvas, const std::string& value);
|
|
|
|
|
2018-05-18 12:08:59 +00:00
|
|
|
static bool is_layers_editing_enabled(wxGLCanvas* canvas);
|
2018-05-25 14:28:24 +00:00
|
|
|
static bool is_layers_editing_allowed(wxGLCanvas* canvas);
|
2018-06-04 12:28:59 +00:00
|
|
|
static bool is_shader_enabled(wxGLCanvas* canvas);
|
2018-05-18 12:08:59 +00:00
|
|
|
|
2018-06-08 07:40:00 +00:00
|
|
|
static bool is_reload_delayed(wxGLCanvas* canvas);
|
|
|
|
|
2018-05-25 12:05:08 +00:00
|
|
|
static void enable_layers_editing(wxGLCanvas* canvas, bool enable);
|
2018-05-21 12:40:09 +00:00
|
|
|
static void enable_warning_texture(wxGLCanvas* canvas, bool enable);
|
2018-05-21 12:57:43 +00:00
|
|
|
static void enable_legend_texture(wxGLCanvas* canvas, bool enable);
|
2018-05-22 07:02:42 +00:00
|
|
|
static void enable_picking(wxGLCanvas* canvas, bool enable);
|
2018-05-31 11:51:50 +00:00
|
|
|
static void enable_moving(wxGLCanvas* canvas, bool enable);
|
2018-06-13 07:12:16 +00:00
|
|
|
static void enable_gizmos(wxGLCanvas* canvas, bool enable);
|
2018-05-23 07:57:44 +00:00
|
|
|
static void enable_shader(wxGLCanvas* canvas, bool enable);
|
2018-06-05 08:56:55 +00:00
|
|
|
static void enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable);
|
2018-05-23 13:35:11 +00:00
|
|
|
static void allow_multisample(wxGLCanvas* canvas, bool allow);
|
2018-05-21 12:40:09 +00:00
|
|
|
|
2018-05-15 08:32:38 +00:00
|
|
|
static void zoom_to_bed(wxGLCanvas* canvas);
|
|
|
|
static void zoom_to_volumes(wxGLCanvas* canvas);
|
2018-05-15 09:30:11 +00:00
|
|
|
static void select_view(wxGLCanvas* canvas, const std::string& direction);
|
2018-05-29 13:36:09 +00:00
|
|
|
static void set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other);
|
2018-05-29 13:07:06 +00:00
|
|
|
|
|
|
|
static void update_volumes_colors_by_extruder(wxGLCanvas* canvas);
|
2018-06-19 07:46:26 +00:00
|
|
|
static void update_gizmos_data(wxGLCanvas* canvas);
|
2018-05-29 13:07:06 +00:00
|
|
|
|
2018-05-29 11:54:34 +00:00
|
|
|
static void render(wxGLCanvas* canvas);
|
2018-05-30 13:18:45 +00:00
|
|
|
|
2018-06-04 13:42:34 +00:00
|
|
|
static std::vector<double> get_current_print_zs(wxGLCanvas* canvas, bool active_only);
|
|
|
|
static void set_toolpaths_range(wxGLCanvas* canvas, double low, double high);
|
|
|
|
|
2018-05-15 07:50:01 +00:00
|
|
|
static void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
|
2018-05-31 11:51:50 +00:00
|
|
|
static void register_on_double_click_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_right_click_callback(wxGLCanvas* canvas, void* callback);
|
2018-06-08 09:37:07 +00:00
|
|
|
static void register_on_select_object_callback(wxGLCanvas* canvas, void* callback);
|
2018-05-31 14:04:59 +00:00
|
|
|
static void register_on_model_update_callback(wxGLCanvas* canvas, void* callback);
|
2018-06-07 07:22:19 +00:00
|
|
|
static void register_on_remove_object_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_arrange_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback);
|
2018-06-07 09:18:28 +00:00
|
|
|
static void register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback);
|
|
|
|
static void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
|
2018-06-18 13:07:17 +00:00
|
|
|
static void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
|
2018-06-19 07:46:26 +00:00
|
|
|
static void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
|
2018-06-22 09:19:38 +00:00
|
|
|
static void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
|
2018-05-15 07:50:01 +00:00
|
|
|
|
2018-06-06 08:16:58 +00:00
|
|
|
static std::vector<int> load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs);
|
2018-06-07 07:22:19 +00:00
|
|
|
static std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
|
2018-06-06 08:16:58 +00:00
|
|
|
|
2018-06-08 07:40:00 +00:00
|
|
|
static void reload_scene(wxGLCanvas* canvas, bool force);
|
|
|
|
|
2018-06-05 12:09:36 +00:00
|
|
|
static void load_print_toolpaths(wxGLCanvas* canvas);
|
|
|
|
static void load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector<std::string>& str_tool_colors);
|
|
|
|
static void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors);
|
2018-06-05 08:56:55 +00:00
|
|
|
static void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
|
2018-02-06 11:43:25 +00:00
|
|
|
|
|
|
|
static void reset_legend_texture();
|
2018-07-18 13:52:20 +00:00
|
|
|
|
2018-06-05 12:09:36 +00:00
|
|
|
static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GLVolume& volume);
|
|
|
|
static void thick_lines_to_verts(const Lines3& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, GLVolume& volume);
|
2018-06-05 08:56:55 +00:00
|
|
|
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, GLVolume& volume);
|
|
|
|
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GLVolume& volume);
|
|
|
|
static void extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, float print_z, const Point& copy, GLVolume& volume);
|
|
|
|
static void extrusionentity_to_verts(const ExtrusionMultiPath& extrusion_multi_path, float print_z, const Point& copy, GLVolume& volume);
|
|
|
|
static void extrusionentity_to_verts(const ExtrusionEntityCollection& extrusion_entity_collection, float print_z, const Point& copy, GLVolume& volume);
|
|
|
|
static void extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GLVolume& volume);
|
|
|
|
static void polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume);
|
|
|
|
static void point3_to_verts(const Point3& point, double width, double height, GLVolume& volume);
|
2015-01-17 23:36:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|