Fix of slow update when dragging the vertical slider in G-code viewer
with volumetric flow color mapping enabled. Fixes "Volumetric flow rate computes very slowly #5572"
This commit is contained in:
parent
615356b69c
commit
daa0bbdb0c
@ -354,8 +354,12 @@ inline std::string get_time_dhm(float time_in_secs)
|
|||||||
|
|
||||||
#if WIN32
|
#if WIN32
|
||||||
#define SLIC3R_STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + __alignof(TYPE) - 1) / __alignof(TYPE)) * __alignof(TYPE)
|
#define SLIC3R_STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + __alignof(TYPE) - 1) / __alignof(TYPE)) * __alignof(TYPE)
|
||||||
|
//FIXME this is an inprecise hack. Add the hash table size and possibly some estimate of the linked list at each of the used bin.
|
||||||
|
#define SLIC3R_STDUNORDEREDSET_MEMSIZE(NAME, TYPE) NAME.size() * ((sizeof(TYPE) + __alignof(TYPE) - 1) / __alignof(TYPE)) * __alignof(TYPE)
|
||||||
#else
|
#else
|
||||||
#define SLIC3R_STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + alignof(TYPE) - 1) / alignof(TYPE)) * alignof(TYPE)
|
#define SLIC3R_STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + alignof(TYPE) - 1) / alignof(TYPE)) * alignof(TYPE)
|
||||||
|
//FIXME this is an inprecise hack. Add the hash table size and possibly some estimate of the linked list at each of the used bin.
|
||||||
|
#define SLIC3R_STDUNORDEREDSET_MEMSIZE(NAME, TYPE) NAME.size() * ((sizeof(TYPE) + alignof(TYPE) - 1) / alignof(TYPE)) * alignof(TYPE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // slic3r_Utils_hpp_
|
#endif // slic3r_Utils_hpp_
|
||||||
|
@ -147,9 +147,9 @@ void GCodeViewer::TBuffer::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// release cpu memory
|
// release cpu memory
|
||||||
indices = std::vector<IBuffer>();
|
indices.clear();
|
||||||
paths = std::vector<Path>();
|
paths.clear();
|
||||||
render_paths = std::vector<RenderPath>();
|
render_paths.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id)
|
void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id)
|
||||||
@ -781,9 +781,9 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
|
|||||||
unsigned int start_vertex_offset = buffer.start_segment_vertex_offset();
|
unsigned int start_vertex_offset = buffer.start_segment_vertex_offset();
|
||||||
unsigned int end_vertex_offset = buffer.end_segment_vertex_offset();
|
unsigned int end_vertex_offset = buffer.end_segment_vertex_offset();
|
||||||
|
|
||||||
for (size_t i = 0; i < buffer.render_paths.size(); ++i) {
|
size_t i = 0;
|
||||||
|
for (const RenderPath& render_path : buffer.render_paths) {
|
||||||
// get paths segments from buffer paths
|
// get paths segments from buffer paths
|
||||||
const RenderPath& render_path = buffer.render_paths[i];
|
|
||||||
const IndexBuffer& ibuffer = indices[render_path.index_buffer_id];
|
const IndexBuffer& ibuffer = indices[render_path.index_buffer_id];
|
||||||
const Path& path = buffer.paths[render_path.path_id];
|
const Path& path = buffer.paths[render_path.path_id];
|
||||||
float half_width = 0.5f * path.width;
|
float half_width = 0.5f * path.width;
|
||||||
@ -948,6 +948,8 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
|
|||||||
for (const Triangle& t : out_triangles) {
|
for (const Triangle& t : out_triangles) {
|
||||||
fprintf(fp, "f %zu//%zu %zu//%zu %zu//%zu\n", t[0], t[0], t[1], t[1], t[2], t[2]);
|
fprintf(fp, "f %zu//%zu %zu//%zu %zu//%zu\n", t[0], t[0], t[1], t[1], t[2], t[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++ i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -1900,6 +1902,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
// second pass: filter paths by sequential data and collect them by color
|
// second pass: filter paths by sequential data and collect them by color
|
||||||
|
RenderPath *render_path = nullptr;
|
||||||
for (const auto& [buffer, index_buffer_id, path_id] : paths) {
|
for (const auto& [buffer, index_buffer_id, path_id] : paths) {
|
||||||
const Path& path = buffer->paths[path_id];
|
const Path& path = buffer->paths[path_id];
|
||||||
if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first)
|
if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first)
|
||||||
@ -1930,16 +1933,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
default: { color = { 0.0f, 0.0f, 0.0f }; break; }
|
default: { color = { 0.0f, 0.0f, 0.0f }; break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ibuffer_id = index_buffer_id;
|
RenderPath key{ color, static_cast<unsigned int>(index_buffer_id), path_id };
|
||||||
auto it = std::find_if(buffer->render_paths.begin(), buffer->render_paths.end(),
|
if (render_path == nullptr || ! RenderPathPropertyEqual()(*render_path, key))
|
||||||
[color, ibuffer_id](const RenderPath& path) { return path.index_buffer_id == ibuffer_id && path.color == color; });
|
render_path = const_cast<RenderPath*>(&(*buffer->render_paths.emplace(key).first));
|
||||||
if (it == buffer->render_paths.end()) {
|
|
||||||
it = buffer->render_paths.insert(buffer->render_paths.end(), RenderPath());
|
|
||||||
it->color = color;
|
|
||||||
it->path_id = path_id;
|
|
||||||
it->index_buffer_id = index_buffer_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int segments_count = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1;
|
unsigned int segments_count = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1;
|
||||||
unsigned int size_in_indices = 0;
|
unsigned int size_in_indices = 0;
|
||||||
switch (buffer->render_primitive_type)
|
switch (buffer->render_primitive_type)
|
||||||
@ -1948,7 +1944,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
case TBuffer::ERenderPrimitiveType::Line:
|
case TBuffer::ERenderPrimitiveType::Line:
|
||||||
case TBuffer::ERenderPrimitiveType::Triangle: { size_in_indices = buffer->indices_per_segment() * (segments_count - 1); break; }
|
case TBuffer::ERenderPrimitiveType::Triangle: { size_in_indices = buffer->indices_per_segment() * (segments_count - 1); break; }
|
||||||
}
|
}
|
||||||
it->sizes.push_back(size_in_indices);
|
render_path->sizes.push_back(size_in_indices);
|
||||||
|
|
||||||
unsigned int delta_1st = 0;
|
unsigned int delta_1st = 0;
|
||||||
if (path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= path.last.s_id)
|
if (path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= path.last.s_id)
|
||||||
@ -1957,7 +1953,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
if (buffer->render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle)
|
if (buffer->render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle)
|
||||||
delta_1st *= buffer->indices_per_segment();
|
delta_1st *= buffer->indices_per_segment();
|
||||||
|
|
||||||
it->offsets.push_back(static_cast<size_t>((path.first.i_id + delta_1st) * sizeof(unsigned int)));
|
render_path->offsets.push_back(static_cast<size_t>((path.first.i_id + delta_1st) * sizeof(unsigned int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set sequential data to their final value
|
// set sequential data to their final value
|
||||||
@ -2943,7 +2939,7 @@ void GCodeViewer::log_memory_used(const std::string& label, int64_t additional)
|
|||||||
int64_t render_paths_size = 0;
|
int64_t render_paths_size = 0;
|
||||||
for (const TBuffer& buffer : m_buffers) {
|
for (const TBuffer& buffer : m_buffers) {
|
||||||
paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path);
|
paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path);
|
||||||
render_paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.render_paths, RenderPath);
|
render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath);
|
||||||
for (const RenderPath& path : buffer.render_paths) {
|
for (const RenderPath& path : buffer.render_paths) {
|
||||||
render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int);
|
render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int);
|
||||||
render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t);
|
render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t);
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
@ -146,11 +148,35 @@ class GCodeViewer
|
|||||||
// Used to batch the indices needed to render paths
|
// Used to batch the indices needed to render paths
|
||||||
struct RenderPath
|
struct RenderPath
|
||||||
{
|
{
|
||||||
Color color;
|
// Render path property
|
||||||
unsigned int path_id;
|
Color color;
|
||||||
unsigned int index_buffer_id;
|
unsigned int index_buffer_id;
|
||||||
std::vector<unsigned int> sizes;
|
// Render path content
|
||||||
std::vector<size_t> offsets; // use size_t because we need an unsigned int whose size matches pointer's size (used in the call glMultiDrawElements())
|
unsigned int path_id;
|
||||||
|
std::vector<unsigned int> sizes;
|
||||||
|
std::vector<size_t> offsets; // use size_t because we need an unsigned int whose size matches pointer's size (used in the call glMultiDrawElements())
|
||||||
|
};
|
||||||
|
struct RenderPathPropertyHash {
|
||||||
|
size_t operator() (const RenderPath &p) const {
|
||||||
|
// Conver the RGB value to an integer hash.
|
||||||
|
// return (size_t(int(p.color[0] * 255) + 255 * int(p.color[1] * 255) + (255 * 255) * int(p.color[2] * 255)) * 7919) ^ size_t(p.index_buffer_id);
|
||||||
|
return size_t(int(p.color[0] * 255) + 255 * int(p.color[1] * 255) + (255 * 255) * int(p.color[2] * 255)) ^ size_t(p.index_buffer_id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct RenderPathPropertyLower {
|
||||||
|
bool operator() (const RenderPath &l, const RenderPath &r) const {
|
||||||
|
for (int i = 0; i < 3; ++ i)
|
||||||
|
if (l.color[i] < r.color[i])
|
||||||
|
return true;
|
||||||
|
else if (l.color[i] > r.color[i])
|
||||||
|
return false;
|
||||||
|
return l.index_buffer_id < r.index_buffer_id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct RenderPathPropertyEqual {
|
||||||
|
bool operator() (const RenderPath &l, const RenderPath &r) const {
|
||||||
|
return l.color == r.color && l.index_buffer_id == r.index_buffer_id;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// buffer containing data for rendering a specific toolpath type
|
// buffer containing data for rendering a specific toolpath type
|
||||||
@ -169,7 +195,9 @@ class GCodeViewer
|
|||||||
|
|
||||||
std::string shader;
|
std::string shader;
|
||||||
std::vector<Path> paths;
|
std::vector<Path> paths;
|
||||||
std::vector<RenderPath> render_paths;
|
// std::set seems to perform singificantly better, at least on Windows.
|
||||||
|
// std::unordered_set<RenderPath, RenderPathPropertyHash, RenderPathPropertyEqual> render_paths;
|
||||||
|
std::set<RenderPath, RenderPathPropertyLower> render_paths;
|
||||||
bool visible{ false };
|
bool visible{ false };
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
Loading…
Reference in New Issue
Block a user