ENH: use std::shared_ptr to save memory for GLVolume

to save memory for copied objects

JIRA: STUDIO-5984
Change-Id: Ie232287fa2d5b0148cd9bca09c560d8de3db9df7
(cherry picked from commit 4d2382810d99701c572b6faa09442c7cda540563)
This commit is contained in:
lane.wei 2024-01-16 14:54:50 +08:00 committed by Lane.Wei
parent 368625944a
commit 1baf3a1e52
5 changed files with 140 additions and 80 deletions

View File

@ -113,6 +113,8 @@ std::array<float, 4> adjust_color_for_rendering(const std::array<float, 4> &colo
namespace Slic3r {
static std::map<const TriangleMesh*, std::set<GLVolume*>> g_mesh_volumes_map;
#if ENABLE_SMOOTH_NORMALS
static void smooth_normals_corner(TriangleMesh& mesh, std::vector<stl_normal>& normals)
{
@ -436,7 +438,7 @@ void GLVolume::load_render_colors()
RenderColor::colors[RenderCol_Model_Unprintable]= IMColor(GLVolume::UNPRINTABLE_COLOR);
}
GLVolume::GLVolume(float r, float g, float b, float a)
GLVolume::GLVolume(float r, float g, float b, float a, bool create_index_data)
: m_sla_shift_z(0.0)
, m_sinking_contours(*this)
// geometry_id == 0 -> invalid
@ -465,6 +467,8 @@ GLVolume::GLVolume(float r, float g, float b, float a)
color = { r, g, b, a };
set_render_color(color);
mmuseg_ts = 0;
if (create_index_data)
indexed_vertex_array = std::make_shared<GLIndexedVertexArray>();
}
void GLVolume::set_color(const std::array<float, 4>& rgba)
@ -640,9 +644,9 @@ const BoundingBoxf3& GLVolume::transformed_non_sinking_bounding_box() const
void GLVolume::set_range(double min_z, double max_z)
{
this->qverts_range.first = 0;
this->qverts_range.second = this->indexed_vertex_array.quad_indices_size;
this->qverts_range.second = this->indexed_vertex_array->quad_indices_size;
this->tverts_range.first = 0;
this->tverts_range.second = this->indexed_vertex_array.triangle_indices_size;
this->tverts_range.second = this->indexed_vertex_array->triangle_indices_size;
if (! this->print_zs.empty()) {
// The Z layer range is specified.
// First test whether the Z span of this object is not out of (min_z, max_z) completely.
@ -769,7 +773,7 @@ void GLVolume::render(bool with_outline) const
}
else {
glsafe(::glMultMatrixd(world_matrix().data()));
this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
this->indexed_vertex_array->render(this->tverts_range, this->qverts_range);
}
};
@ -796,7 +800,7 @@ void GLVolume::render(bool with_outline) const
if (outline_shader == nullptr)
{
glDisable(GL_STENCIL_TEST);
this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
this->indexed_vertex_array->render(this->tverts_range, this->qverts_range);
break;
}
shader->stop_using();
@ -886,7 +890,7 @@ void GLVolume::render(bool with_outline) const
Transform3d matrix = world_matrix();
matrix.scale(scale);
glsafe(::glMultMatrixd(matrix.data()));
this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
this->indexed_vertex_array->render(this->tverts_range, this->qverts_range);
//BOOST_LOG_TRIVIAL(info) << boost::format(": %1%, outline render for body, shader name %2%")%__LINE__ %shader->get_name();
shader->set_uniform("is_outline", false);
@ -978,7 +982,7 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj
}
else {
glsafe(::glMultMatrixd(world_matrix().data()));
this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
this->indexed_vertex_array->render(this->tverts_range, this->qverts_range);
}
glsafe(::glPopMatrix());
@ -1035,19 +1039,19 @@ void GLWipeTowerVolume::render(bool with_outline) const
}
this->iva_per_colors[i].render();
}
glsafe(::glPopMatrix());
if (this->is_left_handed())
glFrontFace(GL_CCW);
}
bool GLWipeTowerVolume::IsTransparent() {
bool GLWipeTowerVolume::IsTransparent() {
for (size_t i = 0; i < m_colors.size(); i++) {
if (m_colors[i][3] < 1.0f) {
if (m_colors[i][3] < 1.0f) {
return true;
}
}
return false;
return false;
}
std::vector<int> GLVolumeCollection::load_object(
@ -1080,17 +1084,41 @@ int GLVolumeCollection::load_object_volume(
const TriangleMesh &mesh = model_volume->mesh();
std::array<float, 4> color = GLVolume::MODEL_COLOR[((color_by == "volume") ? volume_idx : obj_idx) % 4];
color[3] = model_volume->is_model_part() ? 0.7f : 0.4f;
this->volumes.emplace_back(new GLVolume(color));
GLVolume& v = *this->volumes.back();
GLVolume* new_volume = new GLVolume(color[0], color[1], color[2], color[3], false);
this->volumes.emplace_back(new_volume);
GLVolume& v = *new_volume;
v.set_color(color_from_model_volume(*model_volume));
v.name = model_volume->name;
v.is_text_shape = model_volume->get_text_info().m_text.empty();
const TriangleMesh* mesh_ptr = model_volume->mesh_ptr();
new_volume->ori_mesh = mesh_ptr;
std::map<const TriangleMesh*, std::set<GLVolume*>>::iterator iter = g_mesh_volumes_map.find(mesh_ptr);
if (iter != g_mesh_volumes_map.end()) {
std::set<GLVolume*> & volume_set = iter->second;
if (volume_set.empty()) {
new_volume->indexed_vertex_array = std::make_shared<GLIndexedVertexArray>();
}
else {
GLVolume* first_volume = *(volume_set.begin());
new_volume->indexed_vertex_array = first_volume->indexed_vertex_array;
}
volume_set.emplace(new_volume);
}
else {
new_volume->indexed_vertex_array = std::make_shared<GLIndexedVertexArray>();
std::set<GLVolume*> volume_set;
volume_set.emplace(new_volume);
g_mesh_volumes_map.emplace(mesh_ptr, std::move(volume_set));
}
#if ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.load_mesh(mesh, true);
v.indexed_vertex_array->load_mesh(mesh, true);
#else
v.indexed_vertex_array.load_mesh(mesh);
v.indexed_vertex_array->load_mesh(mesh);
#endif // ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
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())
{
@ -1117,6 +1145,33 @@ int GLVolumeCollection::load_object_volume(
return int(this->volumes.size() - 1);
}
void GLVolumeCollection::clear()
{
for (auto* v : volumes)
{
release_volume(v);
delete v;
}
volumes.clear();
}
void GLVolumeCollection::release_volume (GLVolume* volume)
{
if (volume->ori_mesh) {
std::map<const TriangleMesh*, std::set<GLVolume*>>::iterator iter = g_mesh_volumes_map.find(volume->ori_mesh);
if (iter != g_mesh_volumes_map.end()) {
std::set<GLVolume*> & volume_set = iter->second;
volume_set.erase(volume);
if (volume_set.empty())
g_mesh_volumes_map.erase(iter);
}
else {
//should not happen
}
}
}
// Load SLA auxiliary GLVolumes (for support trees or pad).
// This function produces volumes for multiple instances in a single shot,
// as some object specific mesh conversions may be expensive.
@ -1142,11 +1197,11 @@ void GLVolumeCollection::load_object_auxiliary(
this->volumes.emplace_back(new GLVolume((milestone == slaposPad) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR));
GLVolume& v = *this->volumes.back();
#if ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.load_mesh(mesh, true);
v.indexed_vertex_array->load_mesh(mesh, true);
#else
v.indexed_vertex_array.load_mesh(mesh);
v.indexed_vertex_array->load_mesh(mesh);
#endif // ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
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.
@ -1201,8 +1256,8 @@ int GLVolumeCollection::load_wipe_tower_preview(
v.iva_per_colors[i].load_mesh(color_part);
v.iva_per_colors[i].finalize_geometry(opengl_initialized);
}
v.indexed_vertex_array.load_mesh(wipe_tower_shell);
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
v.indexed_vertex_array->load_mesh(wipe_tower_shell);
v.indexed_vertex_array->finalize_geometry(opengl_initialized);
v.set_convex_hull(wipe_tower_shell);
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle));
@ -1226,7 +1281,7 @@ GLVolume* GLVolumeCollection::new_nontoolpath_volume(const std::array<float, 4>&
GLVolume *out = new GLVolume(rgba);
out->is_extrusion_path = false;
// Reserving number of vertices (3x position + 3x color)
out->indexed_vertex_array.reserve(reserve_vbo_floats / 6);
out->indexed_vertex_array->reserve(reserve_vbo_floats / 6);
this->volumes.emplace_back(out);
return out;
}
@ -1240,10 +1295,10 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
GLVolume* volume = volumes[i];
bool is_transparent = (volume->render_color[3] < 1.0f);
auto tempGlwipeTowerVolume = dynamic_cast<GLWipeTowerVolume *>(volume);
if (tempGlwipeTowerVolume) {
if (tempGlwipeTowerVolume) {
is_transparent = tempGlwipeTowerVolume->IsTransparent();
}
if (((type == GLVolumeCollection::ERenderType::Opaque && !is_transparent) ||
if (((type == GLVolumeCollection::ERenderType::Opaque && !is_transparent) ||
(type == GLVolumeCollection::ERenderType::Transparent && is_transparent) ||
type == GLVolumeCollection::ERenderType::All) &&
(! filter_func || filter_func(*volume)))
@ -1347,12 +1402,12 @@ void GLVolumeCollection::render(
//use -1 ad a invalid type
shader->set_uniform("print_volume.type", -1);
}
bool enable_support;
int support_threshold_angle = get_selection_support_threshold_angle(enable_support);
float normal_z = -::cos(Geometry::deg2rad((float) support_threshold_angle));
shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
shader->set_uniform("slope.actived", m_slope.isGlobalActive && !volume.first->is_modifier && !volume.first->is_wipe_tower);
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
@ -1614,8 +1669,8 @@ void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig *con
const Color& color = colors[extruder_id];
if (!color.text.empty()) {
for (int i = 0; i < 4; ++i) {
if (is_update_alpha == false) {
if (i < 3) {
if (is_update_alpha == false) {
if (i < 3) {
volume->color[i] = (float) color.rgba[i] * inv_255;
}
continue;
@ -2192,7 +2247,7 @@ void _3DScene::thick_lines_to_verts(
double top_z,
GLVolume &volume)
{
thick_lines_to_indexed_vertex_array(lines, widths, heights, closed, top_z, volume.indexed_vertex_array);
thick_lines_to_indexed_vertex_array(lines, widths, heights, closed, top_z, *(volume.indexed_vertex_array));
}
void _3DScene::thick_lines_to_verts(const Lines3& lines,
@ -2201,7 +2256,7 @@ void _3DScene::thick_lines_to_verts(const Lines3& lines,
bool closed,
GLVolume& volume)
{
thick_lines_to_indexed_vertex_array(lines, widths, heights, closed, volume.indexed_vertex_array);
thick_lines_to_indexed_vertex_array(lines, widths, heights, closed, *(volume.indexed_vertex_array));
}
static void thick_point_to_verts(const Vec3crd& point,
@ -2209,7 +2264,7 @@ static void thick_point_to_verts(const Vec3crd& point,
double height,
GLVolume& volume)
{
point_to_indexed_vertex_array(point, width, height, volume.indexed_vertex_array);
point_to_indexed_vertex_array(point, width, height, *(volume.indexed_vertex_array));
}
void _3DScene::extrusionentity_to_verts(const Polyline &polyline, float width, float height, float print_z, GLVolume& volume)

View File

@ -287,7 +287,7 @@ public:
HS_Deselect
};
GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f);
GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f, bool create_index_data = true);
GLVolume(const std::array<float, 4>& rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {}
virtual ~GLVolume() = default;
@ -400,7 +400,8 @@ public:
EHoverState hover;
// Interleaved triangles & normals with indexed triangles & quads.
GLIndexedVertexArray indexed_vertex_array;
std::shared_ptr<GLIndexedVertexArray> indexed_vertex_array;
const TriangleMesh * ori_mesh{nullptr};
// BBS
mutable std::vector<GLIndexedVertexArray> mmuseg_ivas;
mutable ObjectBase::Timestamp mmuseg_ts;
@ -418,9 +419,9 @@ public:
// Bounding box of this volume, in unscaled coordinates.
BoundingBoxf3 bounding_box() const {
BoundingBoxf3 out;
if (! this->indexed_vertex_array.bounding_box().isEmpty()) {
out.min = this->indexed_vertex_array.bounding_box().min().cast<double>();
out.max = this->indexed_vertex_array.bounding_box().max().cast<double>();
if (! this->indexed_vertex_array->bounding_box().isEmpty()) {
out.min = this->indexed_vertex_array->bounding_box().min().cast<double>();
out.max = this->indexed_vertex_array->bounding_box().max().cast<double>();
out.defined = true;
};
return out;
@ -517,7 +518,7 @@ public:
// convex hull
const TriangleMesh* convex_hull() const { return m_convex_hull.get(); }
bool empty() const { return this->indexed_vertex_array.empty(); }
bool empty() const { return this->indexed_vertex_array->empty(); }
void set_range(double low, double high);
@ -527,8 +528,8 @@ public:
//BBS: add simple render function for thumbnail
void simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector<std::array<float, 4>>& extruder_colors) const;
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); }
void release_geometry() { this->indexed_vertex_array.release_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.reset();
@ -546,10 +547,10 @@ public:
// 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 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 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(); }
};
@ -677,7 +678,9 @@ public:
// 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(); }
void clear();
void release_volume (GLVolume* volume);
bool empty() const { return volumes.empty(); }
void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); }

View File

@ -3218,6 +3218,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized, bool force_p
while (true) {
GLVolumePtrs::iterator it = std::find_if(m_shells.volumes.volumes.begin(), m_shells.volumes.volumes.end(), [](GLVolume* volume) { return volume->is_modifier; });
if (it != m_shells.volumes.volumes.end()) {
m_shells.volumes.release_volume(*it);
delete (*it);
m_shells.volumes.volumes.erase(it);
}
@ -4120,7 +4121,7 @@ void GCodeViewer::render_shells()
// before opengl has been initialized for the preview canvas.
// when this happens, the volumes' data have not been sent to gpu yet.
for (GLVolume* v : m_shells.volumes.volumes) {
if (!v->indexed_vertex_array.has_VBOs())
if (!v->indexed_vertex_array->has_VBOs())
v->finalize_geometry(true);
}
@ -4163,7 +4164,7 @@ void GCodeViewer::render_all_plates_stats(const std::vector<const GCodeProcessor
std::vector<float> filament_densities = gcode_result_list.front()->filament_densities;
std::vector<Color> filament_colors = decode_colors(wxGetApp().plater()->get_extruder_colors_from_plater_config(gcode_result_list.back()));
for (int i = 0; i < filament_colors.size(); i++) {
for (int i = 0; i < filament_colors.size(); i++) {
filament_colors[i] = adjust_color_for_rendering(filament_colors[i]);
}
@ -5087,7 +5088,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
}
i++;
}
if (need_scrollable)
ImGui::EndChild();

View File

@ -2385,6 +2385,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
// BBS
if (volume->is_wipe_tower)
deleted_wipe_towers.emplace_back(volume, volume_id);
m_volumes.release_volume(volume);
delete volume;
}
}
@ -2550,22 +2551,22 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
GLVolume &volume = *m_volumes.volumes[it->volume_idx];
if (! volume.offsets.empty() && state.step[istep].timestamp != volume.offsets.front()) {
// The backend either produced a new hollowed mesh, or it invalidated the one that the front end has seen.
volume.indexed_vertex_array.release_geometry();
volume.indexed_vertex_array->release_geometry();
if (state.step[istep].state == PrintStateBase::DONE) {
TriangleMesh mesh = print_object->get_mesh(slaposDrillHoles);
assert(! mesh.empty());
mesh.transform(sla_print->sla_trafo(*m_model->objects[volume.object_idx()]).inverse());
#if ENABLE_SMOOTH_NORMALS
volume.indexed_vertex_array.load_mesh(mesh, true);
volume.indexed_vertex_array->load_mesh(mesh, true);
#else
volume.indexed_vertex_array.load_mesh(mesh);
volume.indexed_vertex_array->load_mesh(mesh);
#endif // ENABLE_SMOOTH_NORMALS
} else {
// Reload the original volume.
#if ENABLE_SMOOTH_NORMALS
volume.indexed_vertex_array.load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true);
volume.indexed_vertex_array->load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true);
#else
volume.indexed_vertex_array.load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh());
volume.indexed_vertex_array->load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh());
#endif // ENABLE_SMOOTH_NORMALS
}
volume.finalize_geometry(true);
@ -2752,14 +2753,14 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume& vol_old, bool gl_initialized, size_t prealloc_size = VERTEX_BUFFER_RESERVE_SIZE)
{
// Assign the large pre-allocated buffers to the new GLVolume.
vol_new.indexed_vertex_array = std::move(vol_old.indexed_vertex_array);
*(vol_new.indexed_vertex_array) = std::move(*(vol_old.indexed_vertex_array));
// Copy the content back to the old GLVolume.
vol_old.indexed_vertex_array = vol_new.indexed_vertex_array;
*(vol_old.indexed_vertex_array) = *(vol_new.indexed_vertex_array);
// Clear the buffers, but keep them pre-allocated.
vol_new.indexed_vertex_array.clear();
vol_new.indexed_vertex_array->clear();
// Just make sure that clear did not clear the reserved memory.
// Reserving number of vertices (3x position + 3x color)
vol_new.indexed_vertex_array.reserve(prealloc_size / 6);
vol_new.indexed_vertex_array->reserve(prealloc_size / 6);
// Finalize the old geometry, possibly move data to the graphics card.
vol_old.finalize_geometry(gl_initialized);
}
@ -8514,19 +8515,19 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume)
GLVolume *volume = m_volumes.new_toolpath_volume(color, VERTEX_BUFFER_RESERVE_SIZE);
for (size_t i = 0; i < skirt_height; ++ i) {
volume->print_zs.emplace_back(print_zs[i]);
volume->offsets.emplace_back(volume->indexed_vertex_array.quad_indices.size());
volume->offsets.emplace_back(volume->indexed_vertex_array.triangle_indices.size());
volume->offsets.emplace_back(volume->indexed_vertex_array->quad_indices.size());
volume->offsets.emplace_back(volume->indexed_vertex_array->triangle_indices.size());
//BBS: usage of m_brim are deleted
_3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), *volume);
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
if (volume->indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
if (volume->indexed_vertex_array->vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
GLVolume &vol = *volume;
volume = m_volumes.new_toolpath_volume(vol.color);
reserve_new_volume_finalize_old_volume(*volume, vol, m_initialized);
}
}
volume->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(volume->indexed_vertex_array.vertices_and_normals_interleaved, volume->indexed_vertex_array.bounding_box());
volume->indexed_vertex_array.finalize_geometry(m_initialized);
volume->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(volume->indexed_vertex_array->vertices_and_normals_interleaved, volume->indexed_vertex_array->bounding_box());
volume->indexed_vertex_array->finalize_geometry(m_initialized);
}
void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume& build_volume, const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values)
@ -8725,7 +8726,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
for (GLVolume *vol : vols)
// Reserving number of vertices (3x position + 3x color)
vol->indexed_vertex_array.reserve(VERTEX_BUFFER_RESERVE_SIZE / 6);
vol->indexed_vertex_array->reserve(VERTEX_BUFFER_RESERVE_SIZE / 6);
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
const Layer *layer = ctxt.layers[idx_layer];
@ -8751,8 +8752,8 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
for (GLVolume *vol : vols)
if (vol->print_zs.empty() || vol->print_zs.back() != layer->print_z) {
vol->print_zs.emplace_back(layer->print_z);
vol->offsets.emplace_back(vol->indexed_vertex_array.quad_indices.size());
vol->offsets.emplace_back(vol->indexed_vertex_array.triangle_indices.size());
vol->offsets.emplace_back(vol->indexed_vertex_array->quad_indices.size());
vol->offsets.emplace_back(vol->indexed_vertex_array->triangle_indices.size());
}
for (const PrintInstance &instance : *ctxt.shifted_copies) {
const Point &copy = instance.shift;
@ -8799,16 +8800,16 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
for (size_t i = 0; i < vols.size(); ++i) {
GLVolume &vol = *vols[i];
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
if (vol.indexed_vertex_array->vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
vols[i] = new_volume(vol.color);
reserve_new_volume_finalize_old_volume(*vols[i], vol, false);
}
}
}
for (GLVolume *vol : vols)
// Ideally one would call vol->indexed_vertex_array.finalize() here to move the buffers to the OpenGL driver,
// 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();
vol->indexed_vertex_array->shrink_to_fit();
});
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info();
@ -8819,8 +8820,8 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
m_volumes.volumes.end());
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) {
GLVolume* v = m_volumes.volumes[i];
v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box());
v->indexed_vertex_array.finalize_geometry(m_initialized);
v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array->vertices_and_normals_interleaved, v->indexed_vertex_array->bounding_box());
v->indexed_vertex_array->finalize_geometry(m_initialized);
}
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
@ -8913,15 +8914,15 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
vols = { new_volume(ctxt.color_support()) };
for (GLVolume *volume : vols)
// Reserving number of vertices (3x position + 3x color)
volume->indexed_vertex_array.reserve(VERTEX_BUFFER_RESERVE_SIZE / 6);
volume->indexed_vertex_array->reserve(VERTEX_BUFFER_RESERVE_SIZE / 6);
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
const std::vector<WipeTower::ToolChangeResult> &layer = ctxt.tool_change(idx_layer);
for (size_t i = 0; i < vols.size(); ++i) {
GLVolume &vol = *vols[i];
if (vol.print_zs.empty() || vol.print_zs.back() != layer.front().print_z) {
vol.print_zs.emplace_back(layer.front().print_z);
vol.offsets.emplace_back(vol.indexed_vertex_array.quad_indices.size());
vol.offsets.emplace_back(vol.indexed_vertex_array.triangle_indices.size());
vol.offsets.emplace_back(vol.indexed_vertex_array->quad_indices.size());
vol.offsets.emplace_back(vol.indexed_vertex_array->triangle_indices.size());
}
}
for (const WipeTower::ToolChangeResult &extrusions : layer) {
@ -8970,13 +8971,13 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
}
for (size_t i = 0; i < vols.size(); ++i) {
GLVolume &vol = *vols[i];
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
if (vol.indexed_vertex_array->vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
vols[i] = new_volume(vol.color);
reserve_new_volume_finalize_old_volume(*vols[i], vol, false);
}
}
for (GLVolume *vol : vols)
vol->indexed_vertex_array.shrink_to_fit();
vol->indexed_vertex_array->shrink_to_fit();
});
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info();
@ -8987,8 +8988,8 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
m_volumes.volumes.end());
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) {
GLVolume* v = m_volumes.volumes[i];
v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box());
v->indexed_vertex_array.finalize_geometry(m_initialized);
v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array->vertices_and_normals_interleaved, v->indexed_vertex_array->bounding_box());
v->indexed_vertex_array->finalize_geometry(m_initialized);
}
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
@ -9012,11 +9013,11 @@ void GLCanvas3D::_load_sla_shells()
m_volumes.volumes.emplace_back(new GLVolume(color));
GLVolume& v = *m_volumes.volumes.back();
#if ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.load_mesh(mesh, true);
v.indexed_vertex_array->load_mesh(mesh, true);
#else
v.indexed_vertex_array.load_mesh(mesh);
v.indexed_vertex_array->load_mesh(mesh);
#endif // ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.finalize_geometry(m_initialized);
v.indexed_vertex_array->finalize_geometry(m_initialized);
v.shader_outside_printer_detection_enabled = outside_printer_detection_enabled;
v.composite_id.volume_id = volume_id;
v.set_instance_offset(unscale(instance.shift.x(), instance.shift.y(), 0.0));

View File

@ -904,7 +904,7 @@ void GLGizmoFdmSupports::run_thread()
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%";
print->set_status(100, L("Support Generated"));
record_timestamp();
}
catch (...) {
@ -927,7 +927,7 @@ _finished:
void GLGizmoFdmSupports::generate_support_volume()
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",before finalize_geometry";
m_support_volume->indexed_vertex_array.finalize_geometry(m_parent.is_initialized());
m_support_volume->indexed_vertex_array->finalize_geometry(m_parent.is_initialized());
std::unique_lock<std::mutex> lck(m_mutex);
m_volume_ready = true;