mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-04 20:44:00 -06:00
Merge remote-tracking branch 'origin' into ys_printable_property
This commit is contained in:
commit
0520da3241
16 changed files with 2709 additions and 2039 deletions
|
@ -12,6 +12,7 @@
|
|||
#include "libslic3r/GCode/Analyzer.hpp"
|
||||
#include "slic3r/GUI/PresetBundle.hpp"
|
||||
#include "libslic3r/Format/STL.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -74,15 +75,19 @@ void GLIndexedVertexArray::load_mesh_full_shading(const TriangleMesh &mesh)
|
|||
}
|
||||
}
|
||||
|
||||
void GLIndexedVertexArray::finalize_geometry() const
|
||||
void GLIndexedVertexArray::finalize_geometry(bool opengl_initialized)
|
||||
{
|
||||
assert(this->vertices_and_normals_interleaved_VBO_id == 0);
|
||||
assert(this->triangle_indices_VBO_id == 0);
|
||||
assert(this->quad_indices_VBO_id == 0);
|
||||
|
||||
this->shrink_to_fit();
|
||||
if (! opengl_initialized) {
|
||||
// Shrink the data vectors to conserve memory in case the data cannot be transfered to the OpenGL driver yet.
|
||||
this->shrink_to_fit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (! empty()) {
|
||||
if (! this->vertices_and_normals_interleaved.empty()) {
|
||||
glsafe(::glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW));
|
||||
|
@ -124,13 +129,8 @@ void GLIndexedVertexArray::release_geometry()
|
|||
|
||||
void GLIndexedVertexArray::render() const
|
||||
{
|
||||
if (this->vertices_and_normals_interleaved_VBO_id == 0)
|
||||
{
|
||||
// sends data to gpu, if not done yet
|
||||
finalize_geometry();
|
||||
if (this->vertices_and_normals_interleaved_VBO_id == 0)
|
||||
return;
|
||||
}
|
||||
assert(this->vertices_and_normals_interleaved_VBO_id != 0);
|
||||
assert(this->triangle_indices_VBO_id != 0 || this->quad_indices_VBO_id != 0);
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
|
||||
|
@ -161,13 +161,8 @@ void GLIndexedVertexArray::render(
|
|||
const std::pair<size_t, size_t>& tverts_range,
|
||||
const std::pair<size_t, size_t>& qverts_range) const
|
||||
{
|
||||
if (this->vertices_and_normals_interleaved_VBO_id == 0)
|
||||
{
|
||||
// sends data to gpu, if not done yet
|
||||
finalize_geometry();
|
||||
if (this->vertices_and_normals_interleaved_VBO_id == 0)
|
||||
return;
|
||||
}
|
||||
assert(this->vertices_and_normals_interleaved_VBO_id != 0);
|
||||
assert(this->triangle_indices_VBO_id != 0 || this->quad_indices_VBO_id != 0);
|
||||
|
||||
// Render using the Vertex Buffer Objects.
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
|
||||
|
@ -423,30 +418,32 @@ bool GLVolume::is_sla_support() const { return this->composite_id.volume_id == -
|
|||
bool GLVolume::is_sla_pad() const { return this->composite_id.volume_id == -int(slaposBasePool); }
|
||||
|
||||
std::vector<int> GLVolumeCollection::load_object(
|
||||
const ModelObject* model_object,
|
||||
const ModelObject *model_object,
|
||||
int obj_idx,
|
||||
const std::vector<int>& instance_idxs,
|
||||
const std::string& color_by)
|
||||
const std::vector<int> &instance_idxs,
|
||||
const std::string &color_by,
|
||||
bool opengl_initialized)
|
||||
{
|
||||
std::vector<int> volumes_idx;
|
||||
for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++volume_idx)
|
||||
for (int instance_idx : instance_idxs)
|
||||
volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx, color_by));
|
||||
volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx, color_by, opengl_initialized));
|
||||
return volumes_idx;
|
||||
}
|
||||
|
||||
int GLVolumeCollection::load_object_volume(
|
||||
const ModelObject* model_object,
|
||||
int obj_idx,
|
||||
int volume_idx,
|
||||
int instance_idx,
|
||||
const std::string& color_by)
|
||||
const ModelObject *model_object,
|
||||
int obj_idx,
|
||||
int volume_idx,
|
||||
int instance_idx,
|
||||
const std::string &color_by,
|
||||
bool opengl_initialized)
|
||||
{
|
||||
const ModelVolume* model_volume = model_object->volumes[volume_idx];
|
||||
const int extruder_id = model_volume->extruder_id();
|
||||
const ModelInstance* instance = model_object->instances[instance_idx];
|
||||
const TriangleMesh& mesh = model_volume->mesh();
|
||||
float color[4];
|
||||
const ModelVolume *model_volume = model_object->volumes[volume_idx];
|
||||
const int extruder_id = model_volume->extruder_id();
|
||||
const ModelInstance *instance = model_object->instances[instance_idx];
|
||||
const TriangleMesh &mesh = model_volume->mesh();
|
||||
float color[4];
|
||||
memcpy(color, GLVolume::MODEL_COLOR[((color_by == "volume") ? volume_idx : obj_idx) % 4], sizeof(float) * 3);
|
||||
/* if (model_volume->is_support_blocker()) {
|
||||
color[0] = 1.0f;
|
||||
|
@ -463,6 +460,7 @@ int GLVolumeCollection::load_object_volume(
|
|||
GLVolume& v = *this->volumes.back();
|
||||
v.set_color_from_model_volume(model_volume);
|
||||
v.indexed_vertex_array.load_mesh(mesh);
|
||||
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
|
||||
v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx);
|
||||
if (model_volume->is_model_part())
|
||||
{
|
||||
|
@ -483,13 +481,14 @@ int GLVolumeCollection::load_object_volume(
|
|||
// This function produces volumes for multiple instances in a single shot,
|
||||
// as some object specific mesh conversions may be expensive.
|
||||
void GLVolumeCollection::load_object_auxiliary(
|
||||
const SLAPrintObject* print_object,
|
||||
const SLAPrintObject *print_object,
|
||||
int obj_idx,
|
||||
// pairs of <instance_idx, print_instance_idx>
|
||||
const std::vector<std::pair<size_t, size_t>>& instances,
|
||||
SLAPrintObjectStep milestone,
|
||||
// Timestamp of the last change of the milestone
|
||||
size_t timestamp)
|
||||
size_t timestamp,
|
||||
bool opengl_initialized)
|
||||
{
|
||||
assert(print_object->is_step_done(milestone));
|
||||
Transform3d mesh_trafo_inv = print_object->trafo().inverse();
|
||||
|
@ -503,6 +502,7 @@ void GLVolumeCollection::load_object_auxiliary(
|
|||
this->volumes.emplace_back(new GLVolume((milestone == slaposBasePool) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR));
|
||||
GLVolume& v = *this->volumes.back();
|
||||
v.indexed_vertex_array.load_mesh(mesh);
|
||||
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
|
||||
v.composite_id = GLVolume::CompositeID(obj_idx, -int(milestone), (int)instance_idx.first);
|
||||
v.geometry_id = std::pair<size_t, size_t>(timestamp, model_instance.id().id);
|
||||
// Create a copy of the convex hull mesh for each instance. Use a move operator on the last instance.
|
||||
|
@ -519,7 +519,7 @@ void GLVolumeCollection::load_object_auxiliary(
|
|||
}
|
||||
|
||||
int GLVolumeCollection::load_wipe_tower_preview(
|
||||
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width)
|
||||
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized)
|
||||
{
|
||||
if (depth < 0.01f)
|
||||
return int(this->volumes.size() - 1);
|
||||
|
@ -572,6 +572,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||
this->volumes.emplace_back(new GLVolume(color));
|
||||
GLVolume& v = *this->volumes.back();
|
||||
v.indexed_vertex_array.load_mesh(mesh);
|
||||
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
|
||||
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
|
||||
v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle));
|
||||
v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0);
|
||||
|
@ -831,6 +832,27 @@ std::vector<double> GLVolumeCollection::get_current_print_zs(bool active_only) c
|
|||
return print_zs;
|
||||
}
|
||||
|
||||
size_t GLVolumeCollection::cpu_memory_used() const
|
||||
{
|
||||
size_t memsize = sizeof(*this) + this->volumes.capacity() * sizeof(GLVolume);
|
||||
for (const GLVolume *volume : this->volumes)
|
||||
memsize += volume->cpu_memory_used();
|
||||
return memsize;
|
||||
}
|
||||
|
||||
size_t GLVolumeCollection::gpu_memory_used() const
|
||||
{
|
||||
size_t memsize = 0;
|
||||
for (const GLVolume *volume : this->volumes)
|
||||
memsize += volume->gpu_memory_used();
|
||||
return memsize;
|
||||
}
|
||||
|
||||
std::string GLVolumeCollection::log_memory_info() const
|
||||
{
|
||||
return " (GLVolumeCollection RAM: " + format_memsize_MB(this->cpu_memory_used()) + " GPU: " + format_memsize_MB(this->gpu_memory_used()) + " Both: " + format_memsize_MB(this->gpu_memory_used()) + ")";
|
||||
}
|
||||
|
||||
// caller is responsible for supplying NO lines with zero length
|
||||
static void thick_lines_to_indexed_vertex_array(
|
||||
const Lines &lines,
|
||||
|
@ -1606,6 +1628,7 @@ bool GLArrow::on_init()
|
|||
triangles.emplace_back(7, 13, 6);
|
||||
|
||||
m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles));
|
||||
m_volume.indexed_vertex_array.finalize_geometry(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1719,6 +1742,7 @@ bool GLCurvedArrow::on_init()
|
|||
triangles.emplace_back(vertices_per_level, 2 * vertices_per_level + 1, vertices_per_level + 1);
|
||||
|
||||
m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles));
|
||||
m_volume.indexed_vertex_array.finalize_geometry(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1745,6 +1769,7 @@ bool GLBed::on_init_from_file(const std::string& filename)
|
|||
m_filename = filename;
|
||||
|
||||
m_volume.indexed_vertex_array.load_mesh(model.mesh());
|
||||
m_volume.indexed_vertex_array.finalize_geometry(true);
|
||||
|
||||
float color[4] = { 0.235f, 0.235f, 0.235f, 1.0f };
|
||||
set_color(color, 4);
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
vertices_and_normals_interleaved_VBO_id(0),
|
||||
triangle_indices_VBO_id(0),
|
||||
quad_indices_VBO_id(0)
|
||||
{}
|
||||
{ assert(! rhs.has_VBOs()); }
|
||||
GLIndexedVertexArray(GLIndexedVertexArray &&rhs) :
|
||||
vertices_and_normals_interleaved(std::move(rhs.vertices_and_normals_interleaved)),
|
||||
triangle_indices(std::move(rhs.triangle_indices)),
|
||||
|
@ -72,7 +72,7 @@ public:
|
|||
vertices_and_normals_interleaved_VBO_id(0),
|
||||
triangle_indices_VBO_id(0),
|
||||
quad_indices_VBO_id(0)
|
||||
{}
|
||||
{ assert(! rhs.has_VBOs()); }
|
||||
|
||||
~GLIndexedVertexArray() { release_geometry(); }
|
||||
|
||||
|
@ -80,14 +80,17 @@ public:
|
|||
{
|
||||
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->m_bounding_box = rhs.m_bounding_box;
|
||||
vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size;
|
||||
triangle_indices_size = rhs.triangle_indices_size;
|
||||
quad_indices_size = rhs.quad_indices_size;
|
||||
assert(quad_indices_VBO_id == 0);
|
||||
assert(rhs.vertices_and_normals_interleaved_VBO_id == 0);
|
||||
assert(rhs.triangle_indices_VBO_id == 0);
|
||||
assert(rhs.quad_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->m_bounding_box = rhs.m_bounding_box;
|
||||
this->vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size;
|
||||
this->triangle_indices_size = rhs.triangle_indices_size;
|
||||
this->quad_indices_size = rhs.quad_indices_size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -95,21 +98,24 @@ public:
|
|||
{
|
||||
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->m_bounding_box = std::move(rhs.m_bounding_box);
|
||||
vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size;
|
||||
triangle_indices_size = rhs.triangle_indices_size;
|
||||
quad_indices_size = rhs.quad_indices_size;
|
||||
assert(quad_indices_VBO_id == 0);
|
||||
assert(rhs.vertices_and_normals_interleaved_VBO_id == 0);
|
||||
assert(rhs.triangle_indices_VBO_id == 0);
|
||||
assert(rhs.quad_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->m_bounding_box = std::move(rhs.m_bounding_box);
|
||||
this->vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size;
|
||||
this->triangle_indices_size = rhs.triangle_indices_size;
|
||||
this->quad_indices_size = rhs.quad_indices_size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Vertices and their normals, interleaved to be used by void glInterleavedArrays(GL_N3F_V3F, 0, x)
|
||||
mutable std::vector<float> vertices_and_normals_interleaved;
|
||||
mutable std::vector<int> triangle_indices;
|
||||
mutable std::vector<int> quad_indices;
|
||||
std::vector<float> vertices_and_normals_interleaved;
|
||||
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.
|
||||
|
@ -119,9 +125,9 @@ public:
|
|||
|
||||
// IDs of the Vertex Array Objects, into which the geometry has been loaded.
|
||||
// Zero if the VBOs are not sent to GPU yet.
|
||||
mutable unsigned int vertices_and_normals_interleaved_VBO_id{ 0 };
|
||||
mutable unsigned int triangle_indices_VBO_id{ 0 };
|
||||
mutable unsigned int quad_indices_VBO_id{ 0 };
|
||||
unsigned int vertices_and_normals_interleaved_VBO_id{ 0 };
|
||||
unsigned int triangle_indices_VBO_id{ 0 };
|
||||
unsigned int quad_indices_VBO_id{ 0 };
|
||||
|
||||
void load_mesh_full_shading(const TriangleMesh &mesh);
|
||||
void load_mesh(const TriangleMesh& mesh) { this->load_mesh_full_shading(mesh); }
|
||||
|
@ -141,12 +147,12 @@ public:
|
|||
|
||||
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));
|
||||
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);
|
||||
this->vertices_and_normals_interleaved.emplace_back(nx);
|
||||
this->vertices_and_normals_interleaved.emplace_back(ny);
|
||||
this->vertices_and_normals_interleaved.emplace_back(nz);
|
||||
this->vertices_and_normals_interleaved.emplace_back(x);
|
||||
this->vertices_and_normals_interleaved.emplace_back(y);
|
||||
this->vertices_and_normals_interleaved.emplace_back(z);
|
||||
|
||||
this->vertices_and_normals_interleaved_size = this->vertices_and_normals_interleaved.size();
|
||||
m_bounding_box.merge(Vec3f(x, y, z).cast<double>());
|
||||
|
@ -167,9 +173,9 @@ public:
|
|||
|
||||
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);
|
||||
this->triangle_indices.emplace_back(idx1);
|
||||
this->triangle_indices.emplace_back(idx2);
|
||||
this->triangle_indices.emplace_back(idx3);
|
||||
this->triangle_indices_size = this->triangle_indices.size();
|
||||
};
|
||||
|
||||
|
@ -180,17 +186,17 @@ public:
|
|||
|
||||
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);
|
||||
this->quad_indices.emplace_back(idx1);
|
||||
this->quad_indices.emplace_back(idx2);
|
||||
this->quad_indices.emplace_back(idx3);
|
||||
this->quad_indices.emplace_back(idx4);
|
||||
this->quad_indices_size = this->quad_indices.size();
|
||||
};
|
||||
|
||||
// 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() const;
|
||||
void finalize_geometry(bool opengl_initialized);
|
||||
// Release the geometry data, release OpenGL VBOs.
|
||||
void release_geometry();
|
||||
|
||||
|
@ -211,7 +217,7 @@ public:
|
|||
}
|
||||
|
||||
// Shrink the internal storage to tighly fit the data stored.
|
||||
void shrink_to_fit() const {
|
||||
void shrink_to_fit() {
|
||||
this->vertices_and_normals_interleaved.shrink_to_fit();
|
||||
this->triangle_indices.shrink_to_fit();
|
||||
this->quad_indices.shrink_to_fit();
|
||||
|
@ -219,6 +225,22 @@ public:
|
|||
|
||||
const BoundingBoxf3& bounding_box() const { return m_bounding_box; }
|
||||
|
||||
// Return an estimate of the memory consumed by this class.
|
||||
size_t cpu_memory_used() const { return sizeof(*this) + vertices_and_normals_interleaved.capacity() * sizeof(float) + triangle_indices.capacity() * sizeof(int) + quad_indices.capacity() * sizeof(int); }
|
||||
// Return an estimate of the memory held by GPU vertex buffers.
|
||||
size_t gpu_memory_used() const
|
||||
{
|
||||
size_t memsize = 0;
|
||||
if (this->vertices_and_normals_interleaved_VBO_id != 0)
|
||||
memsize += this->vertices_and_normals_interleaved_size * 4;
|
||||
if (this->triangle_indices_VBO_id != 0)
|
||||
memsize += this->triangle_indices_size * 4;
|
||||
if (this->quad_indices_VBO_id != 0)
|
||||
memsize += this->quad_indices_size * 4;
|
||||
return memsize;
|
||||
}
|
||||
size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); }
|
||||
|
||||
private:
|
||||
BoundingBoxf3 m_bounding_box;
|
||||
};
|
||||
|
@ -250,7 +272,7 @@ private:
|
|||
Geometry::Transformation m_volume_transformation;
|
||||
|
||||
// Shift in z required by sla supports+pad
|
||||
double m_sla_shift_z;
|
||||
double m_sla_shift_z;
|
||||
// Bounding box of this volume, in unscaled coordinates.
|
||||
mutable BoundingBoxf3 m_transformed_bounding_box;
|
||||
// Whether or not is needed to recalculate the transformed bounding box.
|
||||
|
@ -422,13 +444,22 @@ public:
|
|||
void render() const;
|
||||
void render(int color_id, int detection_id, int worldmatrix_id) const;
|
||||
|
||||
void finalize_geometry() { this->indexed_vertex_array.finalize_geometry(); }
|
||||
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); }
|
||||
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
|
||||
|
||||
void set_bounding_boxes_as_dirty() { m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; }
|
||||
|
||||
bool is_sla_support() const;
|
||||
bool is_sla_pad() const;
|
||||
|
||||
// Return an estimate of the memory consumed by this class.
|
||||
size_t cpu_memory_used() const {
|
||||
//FIXME what to do wih m_convex_hull?
|
||||
return sizeof(*this) - sizeof(this->indexed_vertex_array) + this->indexed_vertex_array.cpu_memory_used() + this->print_zs.capacity() * sizeof(coordf_t) + this->offsets.capacity() * sizeof(size_t);
|
||||
}
|
||||
// Return an estimate of the memory held by GPU vertex buffers.
|
||||
size_t gpu_memory_used() const { return this->indexed_vertex_array.gpu_memory_used(); }
|
||||
size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); }
|
||||
};
|
||||
|
||||
typedef std::vector<GLVolume*> GLVolumePtrs;
|
||||
|
@ -463,30 +494,33 @@ public:
|
|||
~GLVolumeCollection() { clear(); };
|
||||
|
||||
std::vector<int> load_object(
|
||||
const ModelObject* model_object,
|
||||
const ModelObject *model_object,
|
||||
int obj_idx,
|
||||
const std::vector<int>& instance_idxs,
|
||||
const std::string& color_by);
|
||||
const std::vector<int> &instance_idxs,
|
||||
const std::string &color_by,
|
||||
bool opengl_initialized);
|
||||
|
||||
int load_object_volume(
|
||||
const ModelObject* model_object,
|
||||
int obj_idx,
|
||||
int volume_idx,
|
||||
int instance_idx,
|
||||
const std::string& color_by);
|
||||
const ModelObject *model_object,
|
||||
int obj_idx,
|
||||
int volume_idx,
|
||||
int instance_idx,
|
||||
const std::string &color_by,
|
||||
bool opengl_initialized);
|
||||
|
||||
// Load SLA auxiliary GLVolumes (for support trees or pad).
|
||||
void load_object_auxiliary(
|
||||
const SLAPrintObject* print_object,
|
||||
const SLAPrintObject *print_object,
|
||||
int obj_idx,
|
||||
// pairs of <instance_idx, print_instance_idx>
|
||||
const std::vector<std::pair<size_t, size_t>>& instances,
|
||||
SLAPrintObjectStep milestone,
|
||||
// Timestamp of the last change of the milestone
|
||||
size_t timestamp);
|
||||
size_t timestamp,
|
||||
bool opengl_initialized);
|
||||
|
||||
int load_wipe_tower_preview(
|
||||
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width);
|
||||
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized);
|
||||
|
||||
// Render the volumes by OpenGL.
|
||||
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
|
||||
|
@ -494,7 +528,7 @@ public:
|
|||
// 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() { for (auto* v : volumes) v->finalize_geometry(); }
|
||||
void finalize_geometry(bool opengl_initialized) { for (auto* v : volumes) v->finalize_geometry(opengl_initialized); }
|
||||
// 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(); }
|
||||
|
@ -522,6 +556,14 @@ public:
|
|||
// Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection
|
||||
std::vector<double> get_current_print_zs(bool active_only) const;
|
||||
|
||||
// Return an estimate of the memory consumed by this class.
|
||||
size_t cpu_memory_used() const;
|
||||
// Return an estimate of the memory held by GPU vertex buffers.
|
||||
size_t gpu_memory_used() const;
|
||||
size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); }
|
||||
// Return CPU, GPU and total memory log line.
|
||||
std::string log_memory_info() const;
|
||||
|
||||
private:
|
||||
GLVolumeCollection(const GLVolumeCollection &other);
|
||||
GLVolumeCollection& operator=(const GLVolumeCollection &);
|
||||
|
@ -539,6 +581,7 @@ public:
|
|||
GLModel();
|
||||
virtual ~GLModel();
|
||||
|
||||
// init() / init_from_file() shall be called with the OpenGL context active!
|
||||
bool init() { return on_init(); }
|
||||
bool init_from_file(const std::string& filename) { return on_init_from_file(filename); }
|
||||
|
||||
|
@ -568,7 +611,7 @@ protected:
|
|||
class GLArrow : public GLModel
|
||||
{
|
||||
protected:
|
||||
virtual bool on_init();
|
||||
bool on_init() override;
|
||||
};
|
||||
|
||||
class GLCurvedArrow : public GLModel
|
||||
|
@ -579,13 +622,13 @@ public:
|
|||
explicit GLCurvedArrow(unsigned int resolution);
|
||||
|
||||
protected:
|
||||
virtual bool on_init();
|
||||
bool on_init() override;
|
||||
};
|
||||
|
||||
class GLBed : public GLModel
|
||||
{
|
||||
protected:
|
||||
virtual bool on_init_from_file(const std::string& filename);
|
||||
bool on_init_from_file(const std::string& filename) override;
|
||||
};
|
||||
|
||||
class _3DScene
|
||||
|
|
|
@ -212,7 +212,7 @@ wxPanel* BedShapePanel::init_texture_panel()
|
|||
wxStaticText* lbl = dynamic_cast<wxStaticText*>(e.GetEventObject());
|
||||
if (lbl != nullptr)
|
||||
{
|
||||
wxString tooltip_text = (m_custom_texture == NONE) ? _(L("")) : _(m_custom_texture);
|
||||
wxString tooltip_text = (m_custom_texture == NONE) ? "" : _(m_custom_texture);
|
||||
wxToolTip* tooltip = lbl->GetToolTip();
|
||||
if ((tooltip == nullptr) || (tooltip->GetTip() != tooltip_text))
|
||||
lbl->SetToolTip(tooltip_text);
|
||||
|
@ -280,7 +280,7 @@ wxPanel* BedShapePanel::init_model_panel()
|
|||
wxStaticText* lbl = dynamic_cast<wxStaticText*>(e.GetEventObject());
|
||||
if (lbl != nullptr)
|
||||
{
|
||||
wxString tooltip_text = (m_custom_model == NONE) ? _(L("")) : _(m_custom_model);
|
||||
wxString tooltip_text = (m_custom_model == NONE) ? "" : _(m_custom_model);
|
||||
wxToolTip* tooltip = lbl->GetToolTip();
|
||||
if ((tooltip == nullptr) || (tooltip->GetTip() != tooltip_text))
|
||||
lbl->SetToolTip(tooltip_text);
|
||||
|
|
|
@ -1234,10 +1234,9 @@ bool GLCanvas3D::init()
|
|||
return false;
|
||||
}
|
||||
|
||||
// // on linux the gl context is not valid until the canvas is not shown on screen
|
||||
// // we defer the geometry finalization of volumes until the first call to render()
|
||||
// if (!m_volumes.empty())
|
||||
// m_volumes.finalize_geometry();
|
||||
// on linux the gl context is not valid until the canvas is not shown on screen
|
||||
// we defer the geometry finalization of volumes until the first call to render()
|
||||
m_volumes.finalize_geometry(true);
|
||||
|
||||
if (m_gizmos.is_enabled() && !m_gizmos.init())
|
||||
std::cout << "Unable to initialize gizmos: please, check that all the required textures are available" << std::endl;
|
||||
|
@ -1708,7 +1707,7 @@ std::vector<int> GLCanvas3D::load_object(const ModelObject& model_object, int ob
|
|||
instance_idxs.push_back(i);
|
||||
}
|
||||
}
|
||||
return m_volumes.load_object(&model_object, obj_idx, instance_idxs, m_color_by);
|
||||
return m_volumes.load_object(&model_object, obj_idx, instance_idxs, m_color_by, m_initialized);
|
||||
}
|
||||
|
||||
std::vector<int> GLCanvas3D::load_object(const Model& model, int obj_idx)
|
||||
|
@ -1896,7 +1895,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id);
|
||||
if (it->new_geometry()) {
|
||||
// New volume.
|
||||
m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_color_by);
|
||||
m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_color_by, m_initialized);
|
||||
m_volumes.volumes.back()->geometry_id = key.geometry_id;
|
||||
update_object_list = true;
|
||||
} else {
|
||||
|
@ -1969,7 +1968,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
|
||||
for (size_t istep = 0; istep < sla_steps.size(); ++istep)
|
||||
if (!instances[istep].empty())
|
||||
m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp);
|
||||
m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_initialized);
|
||||
}
|
||||
|
||||
// Shift-up all volumes of the object so that it has the right elevation with respect to the print bed
|
||||
|
@ -2009,7 +2008,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
depth = (900.f/w) * (float)(extruders_count - 1);
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
||||
1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
|
||||
brim_spacing * 4.5f);
|
||||
brim_spacing * 4.5f, m_initialized);
|
||||
if (volume_idx_wipe_tower_old != -1)
|
||||
map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new;
|
||||
}
|
||||
|
@ -2946,7 +2945,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
else if (evt.Moving())
|
||||
{
|
||||
m_mouse.position = pos.cast<double>();
|
||||
std::string tooltip = L("");
|
||||
std::string tooltip = "";
|
||||
|
||||
if (tooltip.empty())
|
||||
tooltip = m_gizmos.get_tooltip();
|
||||
|
@ -3234,7 +3233,7 @@ void GLCanvas3D::do_flatten(const Vec3d& normal, const std::string& snapshot_typ
|
|||
wxGetApp().plater()->take_snapshot(_(snapshot_type));
|
||||
|
||||
m_selection.flattening_rotate(normal);
|
||||
do_rotate(L("")); // avoid taking another snapshot
|
||||
do_rotate(""); // avoid taking another snapshot
|
||||
}
|
||||
|
||||
void GLCanvas3D::do_mirror(const std::string& snapshot_type)
|
||||
|
@ -3637,14 +3636,14 @@ bool GLCanvas3D::_init_undoredo_toolbar()
|
|||
std::string curr_additional_tooltip;
|
||||
m_undoredo_toolbar.get_additional_tooltip(id, curr_additional_tooltip);
|
||||
|
||||
std::string new_additional_tooltip = L("");
|
||||
std::string new_additional_tooltip = "";
|
||||
if (can_undo)
|
||||
wxGetApp().plater()->undo_redo_topmost_string_getter(true, new_additional_tooltip);
|
||||
|
||||
if (new_additional_tooltip != curr_additional_tooltip)
|
||||
{
|
||||
m_undoredo_toolbar.set_additional_tooltip(id, new_additional_tooltip);
|
||||
set_tooltip(L(""));
|
||||
set_tooltip("");
|
||||
}
|
||||
return can_undo;
|
||||
};
|
||||
|
@ -3666,14 +3665,14 @@ bool GLCanvas3D::_init_undoredo_toolbar()
|
|||
std::string curr_additional_tooltip;
|
||||
m_undoredo_toolbar.get_additional_tooltip(id, curr_additional_tooltip);
|
||||
|
||||
std::string new_additional_tooltip = L("");
|
||||
std::string new_additional_tooltip = "";
|
||||
if (can_redo)
|
||||
wxGetApp().plater()->undo_redo_topmost_string_getter(false, new_additional_tooltip);
|
||||
|
||||
if (new_additional_tooltip != curr_additional_tooltip)
|
||||
{
|
||||
m_undoredo_toolbar.set_additional_tooltip(id, new_additional_tooltip);
|
||||
set_tooltip(L(""));
|
||||
set_tooltip("");
|
||||
}
|
||||
return can_redo;
|
||||
};
|
||||
|
@ -4539,6 +4538,7 @@ void GLCanvas3D::_load_print_toolpaths()
|
|||
|
||||
_3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), volume);
|
||||
}
|
||||
volume.indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values)
|
||||
|
@ -4604,7 +4604,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||
std::sort(ctxt.layers.begin(), ctxt.layers.end(), [](const Layer *l1, const Layer *l2) { return l1->print_z < l2->print_z; });
|
||||
|
||||
// Maximum size of an allocation block: 32MB / sizeof(float)
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start" << m_volumes.log_memory_info() << log_memory_info();
|
||||
|
||||
//FIXME Improve the heuristics for a grain size.
|
||||
size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
|
||||
|
@ -4710,16 +4710,22 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||
}
|
||||
}
|
||||
}
|
||||
for (GLVolume *vol : vols)
|
||||
// Ideally one would call vol->indexed_vertex_array.finalize() here to move the buffers to the OpenGL driver,
|
||||
// but this code runs in parallel and the OpenGL driver is not thread safe.
|
||||
vol->indexed_vertex_array.shrink_to_fit();
|
||||
});
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results";
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info();
|
||||
// Remove empty volumes from the newly added volumes.
|
||||
m_volumes.volumes.erase(
|
||||
std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(),
|
||||
[](const GLVolume *volume) { return volume->empty(); }),
|
||||
m_volumes.volumes.end());
|
||||
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i)
|
||||
m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end";
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
|
||||
}
|
||||
|
||||
void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors)
|
||||
|
@ -4776,7 +4782,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
|||
ctxt.wipe_tower_angle = ctxt.print->config().wipe_tower_rotation_angle.value/180.f * PI;
|
||||
ctxt.wipe_tower_pos = Vec2f(ctxt.print->config().wipe_tower_x.value, ctxt.print->config().wipe_tower_y.value);
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start" << m_volumes.log_memory_info() << log_memory_info();
|
||||
|
||||
//FIXME Improve the heuristics for a grain size.
|
||||
size_t n_items = print->wipe_tower_data().tool_changes.size() + (ctxt.priming.empty() ? 0 : 1);
|
||||
|
@ -4874,16 +4880,20 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
|||
vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
}
|
||||
}
|
||||
for (GLVolume *vol : vols)
|
||||
vol->indexed_vertex_array.shrink_to_fit();
|
||||
});
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results";
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info();
|
||||
// Remove empty volumes from the newly added volumes.
|
||||
m_volumes.volumes.erase(
|
||||
std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(),
|
||||
[](const GLVolume *volume) { return volume->empty(); }),
|
||||
m_volumes.volumes.end());
|
||||
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i)
|
||||
m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end";
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
|
||||
}
|
||||
|
||||
static inline int hex_digit_to_int(const char c)
|
||||
|
@ -4896,6 +4906,8 @@ static inline int hex_digit_to_int(const char c)
|
|||
|
||||
void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - start" << m_volumes.log_memory_info() << log_memory_info();
|
||||
|
||||
// helper functions to select data in dependence of the extrusion view type
|
||||
struct Helper
|
||||
{
|
||||
|
@ -5011,6 +5023,8 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
|
|||
if (filters.empty())
|
||||
return;
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - create volumes" << m_volumes.log_memory_info() << log_memory_info();
|
||||
|
||||
// creates a new volume for each filter
|
||||
for (Filter& filter : filters)
|
||||
{
|
||||
|
@ -5041,6 +5055,8 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - populate volumes" << m_volumes.log_memory_info() << log_memory_info();
|
||||
|
||||
// populates volumes
|
||||
for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers)
|
||||
{
|
||||
|
@ -5058,6 +5074,12 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finalize volumes and sends geometry to gpu
|
||||
for (size_t i = initial_volumes_count; i < m_volumes.volumes.size(); ++i)
|
||||
m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - end" << m_volumes.log_memory_info() << log_memory_info();
|
||||
}
|
||||
|
||||
void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
|
||||
|
@ -5102,6 +5124,10 @@ void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data,
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
// finalize volumes and sends geometry to gpu
|
||||
for (size_t i = initial_volumes_count; i < m_volumes.volumes.size(); ++i)
|
||||
m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_travel_paths_by_type(const GCodePreviewData& preview_data)
|
||||
|
@ -5330,6 +5356,7 @@ void GLCanvas3D::_load_gcode_retractions(const GCodePreviewData& preview_data)
|
|||
|
||||
_3DScene::point3_to_verts(position.position, position.width, position.height, *volume);
|
||||
}
|
||||
volume->indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5357,6 +5384,7 @@ void GLCanvas3D::_load_gcode_unretractions(const GCodePreviewData& preview_data)
|
|||
|
||||
_3DScene::point3_to_verts(position.position, position.width, position.height, *volume);
|
||||
}
|
||||
volume->indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5382,7 +5410,7 @@ void GLCanvas3D::_load_fff_shells()
|
|||
instance_ids[i] = i;
|
||||
}
|
||||
|
||||
m_volumes.load_object(model_obj, object_id, instance_ids, "object");
|
||||
m_volumes.load_object(model_obj, object_id, instance_ids, "object", m_initialized);
|
||||
|
||||
++object_id;
|
||||
}
|
||||
|
@ -5404,7 +5432,7 @@ void GLCanvas3D::_load_fff_shells()
|
|||
if (!print->is_step_done(psWipeTower))
|
||||
depth = (900.f/config.wipe_tower_width) * (float)(extruders_count - 1);
|
||||
m_volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
|
||||
!print->is_step_done(psWipeTower), brim_spacing * 4.5f);
|
||||
!print->is_step_done(psWipeTower), brim_spacing * 4.5f, m_initialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1778,7 +1778,7 @@ void ObjectList::del_subobject_item(wxDataViewItem& item)
|
|||
m_objects_model->Delete(item);
|
||||
|
||||
if (show_msg)
|
||||
Slic3r::GUI::show_error(nullptr, _(L("From Object List You can't delete the last intance from object.")));
|
||||
Slic3r::GUI::show_error(nullptr, _(L("Last instance of an object cannot be deleted.")));
|
||||
}
|
||||
|
||||
void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item)
|
||||
|
@ -1880,7 +1880,7 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
|
|||
}
|
||||
else if (type == itInstance) {
|
||||
if (object->instances.size() == 1) {
|
||||
Slic3r::GUI::show_error(nullptr, _(L("From Object List You can't delete the last intance from object.")));
|
||||
Slic3r::GUI::show_error(nullptr, _(L("Last instance of an object cannot be deleted.")));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2870,6 +2870,9 @@ void ObjectList::update_selections_on_canvas()
|
|||
wxDataViewItemArray sels;
|
||||
GetSelections(sels);
|
||||
|
||||
// clear selection before adding new elements
|
||||
selection.clear(); //OR remove_all()?
|
||||
|
||||
for (auto item : sels)
|
||||
{
|
||||
add_to_selection(item, selection, instance_idx, mode);
|
||||
|
|
|
@ -287,8 +287,8 @@ bool MainFrame::can_send_gcode() const
|
|||
if (m_plater->model().objects.empty())
|
||||
return false;
|
||||
|
||||
const auto prin_host_opt =wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionString>("print_host");
|
||||
return prin_host_opt != nullptr && !prin_host_opt->value.empty();
|
||||
const auto print_host_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionString>("print_host");
|
||||
return print_host_opt != nullptr && !print_host_opt->value.empty();
|
||||
}
|
||||
|
||||
bool MainFrame::can_slice() const
|
||||
|
|
|
@ -2302,7 +2302,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
}
|
||||
}
|
||||
|
||||
if (new_model != nullptr) {
|
||||
if (new_model != nullptr && new_model->objects.size() > 1) {
|
||||
wxMessageDialog dlg(q, _(L(
|
||||
"Multiple objects were loaded for a multi-material printer.\n"
|
||||
"Instead of considering them as multiple objects, should I consider\n"
|
||||
|
@ -4550,7 +4550,7 @@ void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& ou
|
|||
return;
|
||||
}
|
||||
|
||||
out_text = L("");
|
||||
out_text = "";
|
||||
}
|
||||
|
||||
void Plater::on_extruders_change(int num_extruders)
|
||||
|
|
|
@ -100,6 +100,7 @@ void Selection::set_volumes(GLVolumePtrs* volumes)
|
|||
update_valid();
|
||||
}
|
||||
|
||||
// Init shall be called from the OpenGL render function, so that the OpenGL context is initialized!
|
||||
bool Selection::init()
|
||||
{
|
||||
if (!m_arrow.init())
|
||||
|
|
|
@ -58,21 +58,19 @@ std::string get_mem_info(bool format_as_html)
|
|||
std::string b_end = format_as_html ? "</b>" : "";
|
||||
std::string line_end = format_as_html ? "<br>" : "\n";
|
||||
|
||||
const Slic3r::UndoRedo::Stack &stack = wxGetApp().plater()->undo_redo_stack_main();
|
||||
out << b_start << "RAM size reserved for the Undo / Redo stack [MB]: " << b_end << Slic3r::format_memsize_MB(stack.get_memory_limit()) << line_end;
|
||||
out << b_start << "RAM size occupied by the Undo / Redo stack [MB]: " << b_end << Slic3r::format_memsize_MB(stack.memsize()) << line_end << line_end;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ::GetCurrentProcessId());
|
||||
if (hProcess != nullptr) {
|
||||
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||
if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)))
|
||||
out << b_start << "WorkingSet [MB]: " << b_end << format_memsize_MB(pmc.WorkingSetSize) << line_end
|
||||
<< b_start << "PrivateBytes [MB]: " << b_end << format_memsize_MB(pmc.PrivateUsage) << line_end
|
||||
<< b_start << "Pagefile(peak) [MB]: " << b_end << format_memsize_MB(pmc.PagefileUsage) << "(" << format_memsize_MB(pmc.PeakPagefileUsage) << ")" << line_end;
|
||||
CloseHandle(hProcess);
|
||||
std::string mem_info_str = log_memory_info(true);
|
||||
std::istringstream mem_info(mem_info_str);
|
||||
std::string value;
|
||||
while (std::getline(mem_info, value, ':')) {
|
||||
out << b_start << (value+": ") << b_end;
|
||||
std::getline(mem_info, value, ';');
|
||||
out << value << line_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
const Slic3r::UndoRedo::Stack &stack = wxGetApp().plater()->undo_redo_stack_main();
|
||||
out << b_start << "RAM size reserved for the Undo / Redo stack: " << b_end << Slic3r::format_memsize_MB(stack.get_memory_limit()) << line_end;
|
||||
out << b_start << "RAM size occupied by the Undo / Redo stack: " << b_end << Slic3r::format_memsize_MB(stack.memsize()) << line_end << line_end;
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue