mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-07 12:31:47 +08:00
Fixed a bug, where the GL context was not being activated with _set_current()
as _set_current() tested for visibility of the window on the screen. Improved memory management by: 1) Allocating small (around 3MB) vertex buffers to be sent to the GPU. 2) Passing the small vertex buffers to the GPU as quickly as possible. A bit of copy / paste refactoring into common functions.
This commit is contained in:
parent
9cbfe8f5ef
commit
85d9a16563
@ -585,6 +585,23 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
||||
return int(this->volumes.size() - 1);
|
||||
}
|
||||
|
||||
GLVolume* GLVolumeCollection::new_toolpath_volume(const float *rgba, size_t reserve_vbo_floats)
|
||||
{
|
||||
GLVolume *out = new_nontoolpath_volume(rgba, reserve_vbo_floats);
|
||||
out->is_extrusion_path = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
GLVolume* GLVolumeCollection::new_nontoolpath_volume(const float *rgba, size_t reserve_vbo_floats)
|
||||
{
|
||||
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);
|
||||
this->volumes.emplace_back(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func)
|
||||
{
|
||||
GLVolumeWithIdAndZList list;
|
||||
|
@ -522,6 +522,9 @@ public:
|
||||
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, bool opengl_initialized);
|
||||
|
||||
GLVolume* new_toolpath_volume(const float *rgba, size_t reserve_vbo_floats = 0);
|
||||
GLVolume* new_nontoolpath_volume(const float *rgba, size_t reserve_vbo_floats = 0);
|
||||
|
||||
// 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;
|
||||
|
||||
|
@ -70,6 +70,11 @@ static const float ERROR_BG_DARK_COLOR[3] = { 0.478f, 0.192f, 0.039f };
|
||||
static const float ERROR_BG_LIGHT_COLOR[3] = { 0.753f, 0.192f, 0.039f };
|
||||
//static const float AXES_COLOR[3][3] = { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
|
||||
|
||||
// Number of floats
|
||||
static const float MAX_VERTEX_BUFFER_SIZE = 131072 * 6; // 3.15MB
|
||||
// Reserve size in number of floats.
|
||||
static const float VERTEX_BUFFER_RESERVE_SIZE = 131072 * 2; // 1.05MB
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@ -1518,14 +1523,8 @@ void GLCanvas3D::render()
|
||||
if (m_canvas == nullptr)
|
||||
return;
|
||||
|
||||
#ifndef __WXMAC__
|
||||
// on Mac this check causes flickering when changing view
|
||||
if (!_is_shown_on_screen())
|
||||
return;
|
||||
#endif // __WXMAC__
|
||||
|
||||
// ensures this canvas is current and initialized
|
||||
if (!_set_current() || !_3DScene::init(m_canvas))
|
||||
if (! _is_shown_on_screen() || !_set_current() || !_3DScene::init(m_canvas))
|
||||
return;
|
||||
|
||||
#if ENABLE_RENDER_STATISTICS
|
||||
@ -2084,6 +2083,52 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume& vol_old, bool gl_initialized)
|
||||
{
|
||||
// Assign the large pre-allocated buffers to the new GLVolume.
|
||||
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;
|
||||
// Clear the buffers, but keep them pre-allocated.
|
||||
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(VERTEX_BUFFER_RESERVE_SIZE / 6);
|
||||
// Finalize the old geometry, possibly move data to the graphics card.
|
||||
vol_old.finalize_geometry(gl_initialized);
|
||||
}
|
||||
|
||||
static void load_gcode_retractions(const GCodePreviewData::Retraction& retractions, GLCanvas3D::GCodePreviewVolumeIndex::EType extrusion_type, GLVolumeCollection &volumes, GLCanvas3D::GCodePreviewVolumeIndex &volume_index, bool gl_initialized)
|
||||
{
|
||||
volume_index.first_volumes.emplace_back(extrusion_type, 0, (unsigned int)volumes.volumes.size());
|
||||
|
||||
// nothing to render, return
|
||||
if (retractions.positions.empty())
|
||||
return;
|
||||
|
||||
GLVolume *volume = volumes.new_nontoolpath_volume(retractions.color.rgba, VERTEX_BUFFER_RESERVE_SIZE);
|
||||
|
||||
GCodePreviewData::Retraction::PositionsList copy(retractions.positions);
|
||||
std::sort(copy.begin(), copy.end(), [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2) { return p1.position(2) < p2.position(2); });
|
||||
|
||||
for (const GCodePreviewData::Retraction::Position& position : copy)
|
||||
{
|
||||
volume->print_zs.push_back(unscale<double>(position.position(2)));
|
||||
volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
|
||||
volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
|
||||
|
||||
_3DScene::point3_to_verts(position.position, position.width, position.height, *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) {
|
||||
GLVolume &vol = *volume;
|
||||
volume = volumes.new_nontoolpath_volume(vol.color);
|
||||
reserve_new_volume_finalize_old_volume(*volume, vol, gl_initialized);
|
||||
}
|
||||
}
|
||||
volume->indexed_vertex_array.finalize_geometry(gl_initialized);
|
||||
}
|
||||
|
||||
void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors)
|
||||
{
|
||||
const Print *print = this->fff_print();
|
||||
@ -2099,8 +2144,8 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const
|
||||
|
||||
_load_gcode_extrusion_paths(preview_data, tool_colors);
|
||||
_load_gcode_travel_paths(preview_data, tool_colors);
|
||||
_load_gcode_retractions(preview_data);
|
||||
_load_gcode_unretractions(preview_data);
|
||||
load_gcode_retractions(preview_data.retraction, GCodePreviewVolumeIndex::Retraction, m_volumes, m_gcode_preview_volume_index, m_initialized);
|
||||
load_gcode_retractions(preview_data.unretraction, GCodePreviewVolumeIndex::Unretraction, m_volumes, m_gcode_preview_volume_index, m_initialized);
|
||||
|
||||
if (!m_volumes.empty())
|
||||
{
|
||||
@ -2129,6 +2174,8 @@ void GLCanvas3D::load_sla_preview()
|
||||
if ((m_canvas != nullptr) && (print != nullptr))
|
||||
{
|
||||
_set_current();
|
||||
// Release OpenGL data before generating new data.
|
||||
this->reset_volumes();
|
||||
_load_sla_shells();
|
||||
_update_sla_shells_outside_state();
|
||||
_show_warning_texture_if_needed(WarningTexture::SlaSupportsOutside);
|
||||
@ -2143,18 +2190,13 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, c
|
||||
|
||||
_set_current();
|
||||
|
||||
// Release OpenGL data before generating new data.
|
||||
this->reset_volumes();
|
||||
|
||||
_load_print_toolpaths();
|
||||
_load_wipe_tower_toolpaths(str_tool_colors);
|
||||
for (const PrintObject* object : print->objects())
|
||||
{
|
||||
if (object != nullptr)
|
||||
_load_print_object_toolpaths(*object, str_tool_colors, color_print_values);
|
||||
}
|
||||
|
||||
for (GLVolume* volume : m_volumes.volumes)
|
||||
{
|
||||
volume->is_extrusion_path = true;
|
||||
}
|
||||
_load_print_object_toolpaths(*object, str_tool_colors, color_print_values);
|
||||
|
||||
_update_toolpath_volumes_outside_state();
|
||||
_show_warning_texture_if_needed(WarningTexture::ToolpathOutside);
|
||||
@ -3716,11 +3758,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
|
||||
|
||||
bool GLCanvas3D::_set_current()
|
||||
{
|
||||
if (_is_shown_on_screen() && (m_context != nullptr)) {
|
||||
return m_canvas->SetCurrent(*m_context);
|
||||
}
|
||||
|
||||
return false;
|
||||
return m_context != nullptr && m_canvas->SetCurrent(*m_context);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_resize(unsigned int w, unsigned int h)
|
||||
@ -4547,18 +4585,23 @@ void GLCanvas3D::_load_print_toolpaths()
|
||||
if (print_zs.size() > skirt_height)
|
||||
print_zs.erase(print_zs.begin() + skirt_height, print_zs.end());
|
||||
|
||||
m_volumes.volumes.emplace_back(new GLVolume(color));
|
||||
GLVolume& volume = *m_volumes.volumes.back();
|
||||
for (size_t i = 0; i < skirt_height; ++i) {
|
||||
volume.print_zs.push_back(print_zs[i]);
|
||||
volume.offsets.push_back(volume.indexed_vertex_array.quad_indices.size());
|
||||
volume.offsets.push_back(volume.indexed_vertex_array.triangle_indices.size());
|
||||
if (i == 0)
|
||||
_3DScene::extrusionentity_to_verts(print->brim(), print_zs[i], Point(0, 0), volume);
|
||||
|
||||
_3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), 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.push_back(print_zs[i]);
|
||||
volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
|
||||
volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
|
||||
if (i == 0)
|
||||
_3DScene::extrusionentity_to_verts(print->brim(), print_zs[i], Point(0, 0), *volume);
|
||||
_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) {
|
||||
GLVolume &vol = *volume;
|
||||
volume = m_volumes.new_toolpath_volume(vol.color);
|
||||
reserve_new_volume_finalize_old_volume(*volume, vol, m_initialized);
|
||||
}
|
||||
}
|
||||
volume.indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
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)
|
||||
@ -4575,12 +4618,6 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
||||
const std::vector<float>* tool_colors;
|
||||
const std::vector<double>* color_print_values;
|
||||
|
||||
// Number of vertices (each vertex is 6x4=24 bytes long)
|
||||
static const size_t alloc_size_max() { return 131072; } // 3.15MB
|
||||
// static const size_t alloc_size_max () { return 65536; } // 1.57MB
|
||||
// static const size_t alloc_size_max () { return 32768; } // 786kB
|
||||
static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
|
||||
|
||||
static const float* color_perimeters() { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
|
||||
static const float* color_infill() { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish
|
||||
static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
|
||||
@ -4630,10 +4667,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
||||
size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
|
||||
tbb::spin_mutex new_volume_mutex;
|
||||
auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
|
||||
auto *volume = new GLVolume(color);
|
||||
new_volume_mutex.lock();
|
||||
// Allocate the volume before locking.
|
||||
GLVolume *volume = new GLVolume(color);
|
||||
volume->is_extrusion_path = true;
|
||||
tbb::spin_mutex::scoped_lock lock;
|
||||
// Lock by ROII, so if the emplace_back() fails, the lock will be released.
|
||||
lock.acquire(new_volume_mutex);
|
||||
m_volumes.volumes.emplace_back(volume);
|
||||
new_volume_mutex.unlock();
|
||||
lock.release();
|
||||
return volume;
|
||||
};
|
||||
const size_t volumes_cnt_initial = m_volumes.volumes.size();
|
||||
@ -4671,7 +4712,8 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
||||
else
|
||||
vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
|
||||
for (GLVolume *vol : vols)
|
||||
vol->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
// Reserving number of vertices (3x position + 3x color)
|
||||
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];
|
||||
for (GLVolume *vol : vols)
|
||||
@ -4715,18 +4757,9 @@ 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() / 6 > ctxt.alloc_size_max()) {
|
||||
// Store the vertex arrays and restart their containers,
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
|
||||
vols[i] = new_volume(vol.color);
|
||||
GLVolume &vol_new = *vols[i];
|
||||
// Assign the large pre-allocated buffers to the new GLVolume.
|
||||
vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
|
||||
// Copy the content back to the old GLVolume.
|
||||
vol.indexed_vertex_array = vol_new.indexed_vertex_array;
|
||||
// Clear the buffers, but keep them pre-allocated.
|
||||
vol_new.indexed_vertex_array.clear();
|
||||
// Just make sure that clear did not clear the reserved memory.
|
||||
vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
reserve_new_volume_finalize_old_volume(*vols[i], vol, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4766,10 +4799,6 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
||||
Vec2f wipe_tower_pos;
|
||||
float wipe_tower_angle;
|
||||
|
||||
// Number of vertices (each vertex is 6x4=24 bytes long)
|
||||
static const size_t alloc_size_max() { return 131072; } // 3.15MB
|
||||
static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
|
||||
|
||||
static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
|
||||
|
||||
// For cloring by a tool, return a parsed color.
|
||||
@ -4810,9 +4839,11 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
||||
tbb::spin_mutex new_volume_mutex;
|
||||
auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
|
||||
auto *volume = new GLVolume(color);
|
||||
new_volume_mutex.lock();
|
||||
volume->is_extrusion_path = true;
|
||||
tbb::spin_mutex::scoped_lock lock;
|
||||
lock.acquire(new_volume_mutex);
|
||||
m_volumes.volumes.emplace_back(volume);
|
||||
new_volume_mutex.unlock();
|
||||
lock.release();
|
||||
return volume;
|
||||
};
|
||||
const size_t volumes_cnt_initial = m_volumes.volumes.size();
|
||||
@ -4829,7 +4860,8 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
||||
else
|
||||
vols = { new_volume(ctxt.color_support()) };
|
||||
for (GLVolume *volume : vols)
|
||||
volume->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
// Reserving number of vertices (3x position + 3x color)
|
||||
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) {
|
||||
@ -4886,18 +4918,9 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
||||
}
|
||||
for (size_t i = 0; i < vols.size(); ++i) {
|
||||
GLVolume &vol = *vols[i];
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
|
||||
// Store the vertex arrays and restart their containers,
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
|
||||
vols[i] = new_volume(vol.color);
|
||||
GLVolume &vol_new = *vols[i];
|
||||
// Assign the large pre-allocated buffers to the new GLVolume.
|
||||
vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
|
||||
// Copy the content back to the old GLVolume.
|
||||
vol.indexed_vertex_array = vol_new.indexed_vertex_array;
|
||||
// Clear the buffers, but keep them pre-allocated.
|
||||
vol_new.indexed_vertex_array.clear();
|
||||
// Just make sure that clear did not clear the reserved memory.
|
||||
vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
reserve_new_volume_finalize_old_volume(*vols[i], vol, false);
|
||||
}
|
||||
}
|
||||
for (GLVolume *vol : vols)
|
||||
@ -5049,15 +5072,9 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
|
||||
for (Filter& filter : filters)
|
||||
{
|
||||
m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Extrusion, (unsigned int)filter.role, (unsigned int)m_volumes.volumes.size());
|
||||
GLVolume* volume = new GLVolume(Helper::path_color(preview_data, tool_colors, filter.value).rgba);
|
||||
if (volume != nullptr)
|
||||
{
|
||||
filter.volume = volume;
|
||||
volume->is_extrusion_path = true;
|
||||
m_volumes.volumes.emplace_back(volume);
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
filter.volume = m_volumes.new_toolpath_volume(Helper::path_color(preview_data, tool_colors, filter.value).rgba, VERTEX_BUFFER_RESERVE_SIZE);
|
||||
} catch (std::bad_alloc& /* err */) {
|
||||
// an error occourred - restore to previous state and return
|
||||
m_gcode_preview_volume_index.first_volumes.pop_back();
|
||||
if (initial_volumes_count != m_volumes.volumes.size())
|
||||
@ -5065,11 +5082,9 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
|
||||
GLVolumePtrs::iterator begin = m_volumes.volumes.begin() + initial_volumes_count;
|
||||
GLVolumePtrs::iterator end = m_volumes.volumes.end();
|
||||
for (GLVolumePtrs::iterator it = begin; it < end; ++it)
|
||||
{
|
||||
GLVolume* volume = *it;
|
||||
delete volume;
|
||||
}
|
||||
delete *it;
|
||||
m_volumes.volumes.erase(begin, end);
|
||||
//FIXME rethrow bad_alloc?
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -5086,18 +5101,25 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
|
||||
FiltersList::iterator filter = std::find(filters.begin(), filters.end(), Filter(path_filter, path.role()));
|
||||
if (filter != filters.end())
|
||||
{
|
||||
filter->volume->print_zs.push_back(layer.z);
|
||||
filter->volume->offsets.push_back(filter->volume->indexed_vertex_array.quad_indices.size());
|
||||
filter->volume->offsets.push_back(filter->volume->indexed_vertex_array.triangle_indices.size());
|
||||
GLVolume &vol = *filter->volume;
|
||||
vol.print_zs.push_back(layer.z);
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
|
||||
|
||||
_3DScene::extrusionentity_to_verts(path, layer.z, *filter->volume);
|
||||
_3DScene::extrusionentity_to_verts(path, layer.z, vol);
|
||||
|
||||
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
|
||||
filter->volume = m_volumes.new_toolpath_volume(vol.color);
|
||||
reserve_new_volume_finalize_old_volume(*filter->volume, vol, m_initialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
// Finalize volumes and sends geometry to gpu
|
||||
for (Filter &filter : filters)
|
||||
filter.volume->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();
|
||||
}
|
||||
@ -5135,19 +5157,12 @@ void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data,
|
||||
GLVolumePtrs::iterator begin = m_volumes.volumes.begin() + initial_volumes_count;
|
||||
GLVolumePtrs::iterator end = m_volumes.volumes.end();
|
||||
for (GLVolumePtrs::iterator it = begin; it < end; ++it)
|
||||
{
|
||||
GLVolume* volume = *it;
|
||||
delete volume;
|
||||
}
|
||||
delete *it;
|
||||
m_volumes.volumes.erase(begin, end);
|
||||
}
|
||||
|
||||
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)
|
||||
@ -5188,16 +5203,7 @@ bool GLCanvas3D::_travel_paths_by_type(const GCodePreviewData& preview_data)
|
||||
|
||||
// creates a new volume for each type
|
||||
for (Type& type : types)
|
||||
{
|
||||
GLVolume* volume = new GLVolume(preview_data.travel.type_colors[type.value].rgba);
|
||||
if (volume == nullptr)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
type.volume = volume;
|
||||
m_volumes.volumes.emplace_back(volume);
|
||||
}
|
||||
}
|
||||
type.volume = m_volumes.new_nontoolpath_volume(preview_data.travel.type_colors[type.value].rgba, VERTEX_BUFFER_RESERVE_SIZE);
|
||||
|
||||
// populates volumes
|
||||
for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
|
||||
@ -5205,14 +5211,24 @@ bool GLCanvas3D::_travel_paths_by_type(const GCodePreviewData& preview_data)
|
||||
TypesList::iterator type = std::find(types.begin(), types.end(), Type(polyline.type));
|
||||
if (type != types.end())
|
||||
{
|
||||
type->volume->print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
|
||||
type->volume->offsets.push_back(type->volume->indexed_vertex_array.quad_indices.size());
|
||||
type->volume->offsets.push_back(type->volume->indexed_vertex_array.triangle_indices.size());
|
||||
GLVolume &vol = *type->volume;
|
||||
vol.print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
|
||||
|
||||
_3DScene::polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *type->volume);
|
||||
_3DScene::polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, vol);
|
||||
|
||||
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
|
||||
type->volume = m_volumes.new_nontoolpath_volume(vol.color);
|
||||
reserve_new_volume_finalize_old_volume(*type->volume, vol, m_initialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Type &type : types)
|
||||
type.volume->finalize_geometry(m_initialized);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5254,31 +5270,32 @@ bool GLCanvas3D::_travel_paths_by_feedrate(const GCodePreviewData& preview_data)
|
||||
|
||||
// creates a new volume for each feedrate
|
||||
for (Feedrate& feedrate : feedrates)
|
||||
{
|
||||
GLVolume* volume = new GLVolume(preview_data.get_feedrate_color(feedrate.value).rgba);
|
||||
if (volume == nullptr)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
feedrate.volume = volume;
|
||||
m_volumes.volumes.emplace_back(volume);
|
||||
}
|
||||
}
|
||||
feedrate.volume = m_volumes.new_nontoolpath_volume(preview_data.get_feedrate_color(feedrate.value).rgba, VERTEX_BUFFER_RESERVE_SIZE);
|
||||
|
||||
// populates volumes
|
||||
// populates volumes
|
||||
for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
|
||||
{
|
||||
FeedratesList::iterator feedrate = std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate));
|
||||
if (feedrate != feedrates.end())
|
||||
{
|
||||
feedrate->volume->print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
|
||||
feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.quad_indices.size());
|
||||
feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.triangle_indices.size());
|
||||
GLVolume &vol = *feedrate->volume;
|
||||
vol.print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
|
||||
|
||||
_3DScene::polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *feedrate->volume);
|
||||
|
||||
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
|
||||
feedrate->volume = m_volumes.new_nontoolpath_volume(vol.color);
|
||||
reserve_new_volume_finalize_old_volume(*feedrate->volume, vol, m_initialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Feedrate &feedrate : feedrates)
|
||||
feedrate.volume->finalize_geometry(m_initialized);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5322,17 +5339,8 @@ bool GLCanvas3D::_travel_paths_by_tool(const GCodePreviewData& preview_data, con
|
||||
for (Tool& tool : tools)
|
||||
{
|
||||
// tool.value could be invalid (as it was with https://github.com/prusa3d/PrusaSlicer/issues/2179), we better check
|
||||
if (tool.value >= tool_colors.size())
|
||||
continue;
|
||||
|
||||
GLVolume* volume = new GLVolume(tool_colors.data() + tool.value * 4);
|
||||
if (volume == nullptr)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
tool.volume = volume;
|
||||
m_volumes.volumes.emplace_back(volume);
|
||||
}
|
||||
if (tool.value < tool_colors.size())
|
||||
tool.volume = m_volumes.new_nontoolpath_volume(tool_colors.data() + tool.value * 4, VERTEX_BUFFER_RESERVE_SIZE);
|
||||
}
|
||||
|
||||
// populates volumes
|
||||
@ -5341,73 +5349,27 @@ bool GLCanvas3D::_travel_paths_by_tool(const GCodePreviewData& preview_data, con
|
||||
ToolsList::iterator tool = std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id));
|
||||
if (tool != tools.end() && tool->volume != nullptr)
|
||||
{
|
||||
tool->volume->print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
|
||||
tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.quad_indices.size());
|
||||
tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.triangle_indices.size());
|
||||
GLVolume &vol = *tool->volume;
|
||||
vol.print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
|
||||
|
||||
_3DScene::polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *tool->volume);
|
||||
|
||||
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
|
||||
tool->volume = m_volumes.new_nontoolpath_volume(vol.color);
|
||||
reserve_new_volume_finalize_old_volume(*tool->volume, vol, m_initialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Tool& tool : tools)
|
||||
tool.volume->finalize_geometry(m_initialized);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLCanvas3D::_load_gcode_retractions(const GCodePreviewData& preview_data)
|
||||
{
|
||||
m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Retraction, 0, (unsigned int)m_volumes.volumes.size());
|
||||
|
||||
// nothing to render, return
|
||||
if (preview_data.retraction.positions.empty())
|
||||
return;
|
||||
|
||||
GLVolume* volume = new GLVolume(preview_data.retraction.color.rgba);
|
||||
if (volume != nullptr)
|
||||
{
|
||||
m_volumes.volumes.emplace_back(volume);
|
||||
|
||||
GCodePreviewData::Retraction::PositionsList copy(preview_data.retraction.positions);
|
||||
std::sort(copy.begin(), copy.end(), [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2){ return p1.position(2) < p2.position(2); });
|
||||
|
||||
for (const GCodePreviewData::Retraction::Position& position : copy)
|
||||
{
|
||||
volume->print_zs.push_back(unscale<double>(position.position(2)));
|
||||
volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
|
||||
volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
|
||||
|
||||
_3DScene::point3_to_verts(position.position, position.width, position.height, *volume);
|
||||
}
|
||||
volume->indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::_load_gcode_unretractions(const GCodePreviewData& preview_data)
|
||||
{
|
||||
m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Unretraction, 0, (unsigned int)m_volumes.volumes.size());
|
||||
|
||||
// nothing to render, return
|
||||
if (preview_data.unretraction.positions.empty())
|
||||
return;
|
||||
|
||||
GLVolume* volume = new GLVolume(preview_data.unretraction.color.rgba);
|
||||
if (volume != nullptr)
|
||||
{
|
||||
m_volumes.volumes.emplace_back(volume);
|
||||
|
||||
GCodePreviewData::Retraction::PositionsList copy(preview_data.unretraction.positions);
|
||||
std::sort(copy.begin(), copy.end(), [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2){ return p1.position(2) < p2.position(2); });
|
||||
|
||||
for (const GCodePreviewData::Retraction::Position& position : copy)
|
||||
{
|
||||
volume->print_zs.push_back(unscale<double>(position.position(2)));
|
||||
volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
|
||||
volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
|
||||
|
||||
_3DScene::point3_to_verts(position.position, position.width, position.height, *volume);
|
||||
}
|
||||
volume->indexed_vertex_array.finalize_geometry(m_initialized);
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::_load_fff_shells()
|
||||
{
|
||||
size_t initial_volumes_count = m_volumes.volumes.size();
|
||||
|
@ -131,6 +131,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
||||
|
||||
class GLCanvas3D
|
||||
{
|
||||
public:
|
||||
struct GCodePreviewVolumeIndex
|
||||
{
|
||||
enum EType
|
||||
@ -158,6 +159,7 @@ class GLCanvas3D
|
||||
void reset() { first_volumes.clear(); }
|
||||
};
|
||||
|
||||
private:
|
||||
class LayersEditing
|
||||
{
|
||||
public:
|
||||
@ -720,10 +722,6 @@ private:
|
||||
bool _travel_paths_by_type(const GCodePreviewData& preview_data);
|
||||
bool _travel_paths_by_feedrate(const GCodePreviewData& preview_data);
|
||||
bool _travel_paths_by_tool(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
|
||||
// generates gcode retractions geometry
|
||||
void _load_gcode_retractions(const GCodePreviewData& preview_data);
|
||||
// generates gcode unretractions geometry
|
||||
void _load_gcode_unretractions(const GCodePreviewData& preview_data);
|
||||
// generates objects and wipe tower geometry
|
||||
void _load_fff_shells();
|
||||
// Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished.
|
||||
|
Loading…
x
Reference in New Issue
Block a user