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:
parent
368625944a
commit
1baf3a1e52
|
@ -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)
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 © = 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));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue