Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVojtech Bubnik <bubnikv@gmail.com>2021-01-06 17:32:22 +0300
committerVojtech Bubnik <bubnikv@gmail.com>2021-01-06 17:32:31 +0300
commitdaa0bbdb0cfad984565bbd4a17940a65ef28650e (patch)
tree7c23bca0f9d26cc6fce875ce67c6de186b9e75dd
parent615356b69cfcac50d74cb6cc6a957c686c0ae3c9 (diff)
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"
-rw-r--r--src/libslic3r/Utils.hpp4
-rw-r--r--src/slic3r/GUI/GCodeViewer.cpp32
-rw-r--r--src/slic3r/GUI/GCodeViewer.hpp40
3 files changed, 52 insertions, 24 deletions
diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp
index b797c7c19..0979d7f76 100644
--- a/src/libslic3r/Utils.hpp
+++ b/src/libslic3r/Utils.hpp
@@ -354,8 +354,12 @@ inline std::string get_time_dhm(float time_in_secs)
#if WIN32
#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
#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 // slic3r_Utils_hpp_
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index 5a3cff9a4..0af10270e 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -147,9 +147,9 @@ void GCodeViewer::TBuffer::reset()
}
// release cpu memory
- indices = std::vector<IBuffer>();
- paths = std::vector<Path>();
- render_paths = std::vector<RenderPath>();
+ indices.clear();
+ paths.clear();
+ render_paths.clear();
}
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 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
- const RenderPath& render_path = buffer.render_paths[i];
const IndexBuffer& ibuffer = indices[render_path.index_buffer_id];
const Path& path = buffer.paths[render_path.path_id];
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) {
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);
@@ -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
+ RenderPath *render_path = nullptr;
for (const auto& [buffer, index_buffer_id, path_id] : paths) {
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)
@@ -1930,16 +1933,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
default: { color = { 0.0f, 0.0f, 0.0f }; break; }
}
- unsigned int ibuffer_id = index_buffer_id;
- auto it = std::find_if(buffer->render_paths.begin(), buffer->render_paths.end(),
- [color, ibuffer_id](const RenderPath& path) { return path.index_buffer_id == ibuffer_id && path.color == color; });
- 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;
- }
-
+ RenderPath key{ color, static_cast<unsigned int>(index_buffer_id), path_id };
+ if (render_path == nullptr || ! RenderPathPropertyEqual()(*render_path, key))
+ render_path = const_cast<RenderPath*>(&(*buffer->render_paths.emplace(key).first));
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;
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::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;
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)
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
@@ -2943,7 +2939,7 @@ void GCodeViewer::log_memory_used(const std::string& label, int64_t additional)
int64_t render_paths_size = 0;
for (const TBuffer& buffer : m_buffers) {
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) {
render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int);
render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t);
diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp
index 8a3f62015..31092e30d 100644
--- a/src/slic3r/GUI/GCodeViewer.hpp
+++ b/src/slic3r/GUI/GCodeViewer.hpp
@@ -7,6 +7,8 @@
#include <cstdint>
#include <float.h>
+#include <set>
+#include <unordered_set>
namespace Slic3r {
@@ -146,11 +148,35 @@ class GCodeViewer
// Used to batch the indices needed to render paths
struct RenderPath
{
- Color color;
- unsigned int path_id;
- unsigned int index_buffer_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())
+ // Render path property
+ Color color;
+ unsigned int index_buffer_id;
+ // Render path content
+ 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
@@ -169,7 +195,9 @@ class GCodeViewer
std::string shader;
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 };
void reset();