mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-12 11:37:42 +00:00
Let the User Leave Out Infill or Everything But the Shell at Rest Too
A plate of large objects can be slow to draw even when nothing is moving, and the reductions built for dragging cannot help there because they skip layers. So a second choice, applied at all times, leaves out the internal infill roles or everything but the shell while drawing every layer. It is a third index buffer filled by the same walk as the other two and bound whenever the dragging set is not; the options need no counterpart since every layer is drawn. The shell classification is shared, computed once when either choice asks for it. On the 636-layer three-filament fixture at rest, against 448467 segments in 334 ms at full detail: internal infill left out 347208 segments 272 ms everything but the shell 215797 segments 181 ms With the shell at rest and the shell at one layer in four while dragging, the drag frame is 62 ms. At rest with the choice set to nothing, the preview is pixel identical to before.
This commit is contained in:
@@ -212,6 +212,12 @@ void AppConfig::set_defaults()
|
||||
set("preview_reduced_detail_mode", "no_infill");
|
||||
}
|
||||
|
||||
{
|
||||
const std::string mode = get("preview_rest_detail_mode");
|
||||
if (mode != "full" && mode != "no_infill" && mode != "shell")
|
||||
set("preview_rest_detail_mode", "full");
|
||||
}
|
||||
|
||||
if (get("preview_reduced_detail_layer_stride").empty())
|
||||
set("preview_reduced_detail_layer_stride", "4");
|
||||
else {
|
||||
|
||||
@@ -112,6 +112,12 @@ public:
|
||||
void set_reduced_detail_mode(EReducedDetailMode mode);
|
||||
uint32_t get_reduced_detail_layer_stride() const;
|
||||
void set_reduced_detail_layer_stride(uint32_t value);
|
||||
//
|
||||
// ORCA: what is left out even at rest, with every layer drawn. Off draws everything.
|
||||
// EReducedDetailMode::LayersOnly means the same as Off here.
|
||||
//
|
||||
EReducedDetailMode get_rest_detail_mode() const;
|
||||
void set_rest_detail_mode(EReducedDetailMode mode);
|
||||
float get_dim_previous_layers_brightness() const;
|
||||
void set_dim_previous_layers_brightness(float value);
|
||||
//
|
||||
|
||||
@@ -33,6 +33,9 @@ struct Settings
|
||||
bool reduced_detail{ false };
|
||||
EReducedDetailMode reduced_detail_mode{ EReducedDetailMode::Off };
|
||||
uint32_t reduced_detail_layer_stride{ 4 };
|
||||
// ORCA: what is left out even at rest, with every layer drawn. Bound whenever the reduced set
|
||||
// above is not. Off draws everything.
|
||||
EReducedDetailMode rest_detail_mode{ EReducedDetailMode::Off };
|
||||
//
|
||||
// Required update flags
|
||||
//
|
||||
|
||||
@@ -107,6 +107,16 @@ void Viewer::set_reduced_detail_layer_stride(uint32_t value)
|
||||
m_impl->set_reduced_detail_layer_stride(value);
|
||||
}
|
||||
|
||||
EReducedDetailMode Viewer::get_rest_detail_mode() const
|
||||
{
|
||||
return m_impl->get_rest_detail_mode();
|
||||
}
|
||||
|
||||
void Viewer::set_rest_detail_mode(EReducedDetailMode mode)
|
||||
{
|
||||
m_impl->set_rest_detail_mode(mode);
|
||||
}
|
||||
|
||||
void Viewer::set_dim_previous_layers(bool value)
|
||||
{
|
||||
m_impl->set_dim_previous_layers(value);
|
||||
|
||||
@@ -896,10 +896,13 @@ void ViewerImpl::reset()
|
||||
m_enabled_options_count = 0;
|
||||
m_enabled_segments_reduced_count = 0;
|
||||
m_enabled_options_reduced_count = 0;
|
||||
m_enabled_segments_rest_count = 0;
|
||||
m_shell_bitset = BitSet<>();
|
||||
|
||||
m_settings_used_for_ranges = std::nullopt;
|
||||
|
||||
delete_textures(m_enabled_segments_rest_tex_id);
|
||||
delete_buffers(m_enabled_segments_rest_buf_id);
|
||||
delete_textures(m_enabled_options_reduced_tex_id);
|
||||
delete_buffers(m_enabled_options_reduced_buf_id);
|
||||
delete_textures(m_enabled_segments_reduced_tex_id);
|
||||
@@ -1162,6 +1165,11 @@ void ViewerImpl::load(GCodeInputData&& gcode_data)
|
||||
glsafe(glGenTextures(1, &m_enabled_options_reduced_tex_id));
|
||||
glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_options_reduced_tex_id));
|
||||
|
||||
glsafe(glGenBuffers(1, &m_enabled_segments_rest_buf_id));
|
||||
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_rest_buf_id));
|
||||
glsafe(glGenTextures(1, &m_enabled_segments_rest_tex_id));
|
||||
glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_segments_rest_tex_id));
|
||||
|
||||
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0));
|
||||
glsafe(glBindTexture(GL_TEXTURE_BUFFER, old_bound_texture));
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
@@ -1182,9 +1190,9 @@ static bool is_interior_infill(EGCodeExtrusionRole role)
|
||||
role == EGCodeExtrusionRole::InternalBridgeInfill;
|
||||
}
|
||||
|
||||
bool ViewerImpl::reduced_set_keeps(size_t i, const PathVertex& v) const
|
||||
bool ViewerImpl::reduced_set_keeps(EReducedDetailMode mode, size_t i, const PathVertex& v) const
|
||||
{
|
||||
switch (m_settings.reduced_detail_mode) {
|
||||
switch (mode) {
|
||||
case EReducedDetailMode::NoInternalInfill: return !is_interior_infill(v.role);
|
||||
case EReducedDetailMode::ShellOnly: return m_shell_bitset[i];
|
||||
default: return true;
|
||||
@@ -1434,14 +1442,17 @@ void ViewerImpl::update_enabled_entities()
|
||||
#ifndef ENABLE_OPENGL_ES
|
||||
// ORCA: the reduced sets are filled by the same walk, so switching to them costs no rebuild.
|
||||
const bool build_reduced = m_settings.reduced_detail_mode != EReducedDetailMode::Off;
|
||||
const bool build_rest = build_rest_set();
|
||||
std::vector<uint32_t> enabled_segments_reduced;
|
||||
std::vector<uint32_t> enabled_options_reduced;
|
||||
std::vector<uint32_t> enabled_segments_rest;
|
||||
const uint32_t layer_stride = std::max<uint32_t>(1, m_settings.reduced_detail_layer_stride);
|
||||
// Whatever else is dropped, both ends of the visible layer range are kept whole: the top is the
|
||||
// surface the user is looking at, and the only layer drawn at full color in top-layer-only
|
||||
// mode; the bottom is exposed whenever the range is cut short.
|
||||
const Interval& layers_range = m_layers.get_view_range();
|
||||
if (build_reduced && m_settings.reduced_detail_mode == EReducedDetailMode::ShellOnly &&
|
||||
if (((build_reduced && m_settings.reduced_detail_mode == EReducedDetailMode::ShellOnly) ||
|
||||
(build_rest && m_settings.rest_detail_mode == EReducedDetailMode::ShellOnly)) &&
|
||||
m_shell_bitset.size != m_vertices.size())
|
||||
update_shell_bitset();
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
@@ -1494,14 +1505,17 @@ void ViewerImpl::update_enabled_entities()
|
||||
enabled_segments.push_back(static_cast<uint32_t>(i));
|
||||
|
||||
#ifndef ENABLE_OPENGL_ES
|
||||
const bool whole_layer = v.layer_id == layers_range[0] || v.layer_id == layers_range[1];
|
||||
const bool keep_anyway = whole_layer || !v.is_extrusion();
|
||||
if (build_rest && !v.is_option() && (keep_anyway || reduced_set_keeps(m_settings.rest_detail_mode, i, v)))
|
||||
enabled_segments_rest.push_back(static_cast<uint32_t>(i));
|
||||
if (!build_reduced)
|
||||
continue;
|
||||
const bool whole_layer = v.layer_id == layers_range[0] || v.layer_id == layers_range[1];
|
||||
if (!whole_layer && (v.layer_id % layer_stride) != 0)
|
||||
continue;
|
||||
if (v.is_option())
|
||||
enabled_options_reduced.push_back(static_cast<uint32_t>(i));
|
||||
else if (whole_layer || !v.is_extrusion() || reduced_set_keeps(i, v))
|
||||
else if (keep_anyway || reduced_set_keeps(m_settings.reduced_detail_mode, i, v))
|
||||
enabled_segments_reduced.push_back(static_cast<uint32_t>(i));
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
}
|
||||
@@ -1534,6 +1548,14 @@ void ViewerImpl::update_enabled_entities()
|
||||
|
||||
m_enabled_segments_reduced_count = enabled_segments_reduced.size();
|
||||
m_enabled_options_reduced_count = enabled_options_reduced.size();
|
||||
m_enabled_segments_rest_count = enabled_segments_rest.size();
|
||||
|
||||
if (build_rest) {
|
||||
assert(m_enabled_segments_rest_buf_id > 0);
|
||||
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_rest_buf_id));
|
||||
glsafe(glBufferData(GL_TEXTURE_BUFFER, enabled_segments_rest.size() * sizeof(uint32_t),
|
||||
enabled_segments_rest.empty() ? nullptr : enabled_segments_rest.data(), GL_STATIC_DRAW));
|
||||
}
|
||||
|
||||
if (build_reduced) {
|
||||
assert(m_enabled_segments_reduced_buf_id > 0);
|
||||
@@ -1744,6 +1766,14 @@ void ViewerImpl::set_reduced_detail_layer_stride(uint32_t value)
|
||||
m_settings.update_enabled_entities = true;
|
||||
}
|
||||
|
||||
void ViewerImpl::set_rest_detail_mode(EReducedDetailMode mode)
|
||||
{
|
||||
if (m_settings.rest_detail_mode == mode)
|
||||
return;
|
||||
m_settings.rest_detail_mode = mode;
|
||||
m_settings.update_enabled_entities = true;
|
||||
}
|
||||
|
||||
// ORCA: enable/disable darkening of the layers the layer slider is not scrubbed to
|
||||
void ViewerImpl::set_dim_previous_layers(bool value)
|
||||
{
|
||||
|
||||
@@ -101,6 +101,8 @@ public:
|
||||
void set_reduced_detail_mode(EReducedDetailMode mode);
|
||||
uint32_t get_reduced_detail_layer_stride() const { return m_settings.reduced_detail_layer_stride; }
|
||||
void set_reduced_detail_layer_stride(uint32_t value);
|
||||
EReducedDetailMode get_rest_detail_mode() const { return m_settings.rest_detail_mode; }
|
||||
void set_rest_detail_mode(EReducedDetailMode mode);
|
||||
float get_dim_previous_layers_brightness() const { return m_settings.dim_previous_layers_brightness; }
|
||||
void set_dim_previous_layers_brightness(float value);
|
||||
|
||||
@@ -507,6 +509,13 @@ private:
|
||||
unsigned int m_enabled_options_reduced_tex_id{ 0 };
|
||||
size_t m_enabled_options_reduced_count{ 0 };
|
||||
//
|
||||
// OpenGL buffer to store the segments drawn at rest while Settings::rest_detail_mode is not Off.
|
||||
// Every layer is drawn at rest, so the options are the full set and need no counterpart.
|
||||
//
|
||||
unsigned int m_enabled_segments_rest_buf_id{ 0 };
|
||||
unsigned int m_enabled_segments_rest_tex_id{ 0 };
|
||||
size_t m_enabled_segments_rest_count{ 0 };
|
||||
//
|
||||
// Caches for size of data sent to gpu, in bytes
|
||||
//
|
||||
size_t m_positions_tex_size{ 0 };
|
||||
@@ -516,18 +525,22 @@ private:
|
||||
size_t m_enabled_options_tex_size{ 0 };
|
||||
|
||||
// The set the next draw reads from: the reduced one only while the user is dragging, and only
|
||||
// if a reduced set is being built at all.
|
||||
// if a reduced set is being built at all; otherwise the rest set, if one is being built.
|
||||
bool use_reduced_set() const {
|
||||
return m_settings.reduced_detail && m_settings.reduced_detail_mode != EReducedDetailMode::Off;
|
||||
}
|
||||
bool build_rest_set() const {
|
||||
return m_settings.rest_detail_mode != EReducedDetailMode::Off && m_settings.rest_detail_mode != EReducedDetailMode::LayersOnly;
|
||||
}
|
||||
bool use_rest_set() const { return !use_reduced_set() && build_rest_set(); }
|
||||
size_t active_segments_count() const {
|
||||
return use_reduced_set() ? m_enabled_segments_reduced_count : m_enabled_segments_count;
|
||||
return use_reduced_set() ? m_enabled_segments_reduced_count : use_rest_set() ? m_enabled_segments_rest_count : m_enabled_segments_count;
|
||||
}
|
||||
unsigned int active_segments_buf_id() const {
|
||||
return use_reduced_set() ? m_enabled_segments_reduced_buf_id : m_enabled_segments_buf_id;
|
||||
return use_reduced_set() ? m_enabled_segments_reduced_buf_id : use_rest_set() ? m_enabled_segments_rest_buf_id : m_enabled_segments_buf_id;
|
||||
}
|
||||
unsigned int active_segments_tex_id() const {
|
||||
return use_reduced_set() ? m_enabled_segments_reduced_tex_id : m_enabled_segments_tex_id;
|
||||
return use_reduced_set() ? m_enabled_segments_reduced_tex_id : use_rest_set() ? m_enabled_segments_rest_tex_id : m_enabled_segments_tex_id;
|
||||
}
|
||||
size_t active_options_count() const {
|
||||
return use_reduced_set() ? m_enabled_options_reduced_count : m_enabled_options_count;
|
||||
@@ -539,8 +552,8 @@ private:
|
||||
return use_reduced_set() ? m_enabled_options_reduced_tex_id : m_enabled_options_tex_id;
|
||||
}
|
||||
|
||||
// Whether the segment starting at vertex i belongs to the reduced set under the current mode
|
||||
bool reduced_set_keeps(size_t i, const PathVertex& v) const;
|
||||
// Whether the segment starting at vertex i belongs to the set built under the given mode
|
||||
bool reduced_set_keeps(EReducedDetailMode mode, size_t i, const PathVertex& v) const;
|
||||
void update_shell_bitset();
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
|
||||
@@ -1176,6 +1176,7 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
|
||||
m_reduced_detail_while_dragging = get_app_config()->get_bool("preview_reduced_detail_while_dragging");
|
||||
m_reduced_detail_mode = reduced_detail_mode_from_string(get_app_config()->get("preview_reduced_detail_mode"));
|
||||
m_reduced_detail_layer_stride = static_cast<unsigned int>(std::max(1, std::stoi(get_app_config()->get("preview_reduced_detail_layer_stride"))));
|
||||
m_rest_detail_mode = reduced_detail_mode_from_string(get_app_config()->get("preview_rest_detail_mode"));
|
||||
apply_reduced_detail_settings();
|
||||
|
||||
// ORCA: darken the layers the preview layer slider is not scrubbed to
|
||||
@@ -1924,6 +1925,13 @@ void GCodeViewer::apply_reduced_detail_settings()
|
||||
{
|
||||
m_viewer.set_reduced_detail_mode(m_reduced_detail_while_dragging ? m_reduced_detail_mode : libvgcode::EReducedDetailMode::Off);
|
||||
m_viewer.set_reduced_detail_layer_stride(m_reduced_detail_layer_stride);
|
||||
m_viewer.set_rest_detail_mode(m_rest_detail_mode);
|
||||
}
|
||||
|
||||
void GCodeViewer::set_rest_detail_mode(const std::string& mode)
|
||||
{
|
||||
m_rest_detail_mode = reduced_detail_mode_from_string(mode);
|
||||
apply_reduced_detail_settings();
|
||||
}
|
||||
|
||||
void GCodeViewer::set_reduced_detail_while_dragging(bool value)
|
||||
@@ -1946,6 +1954,8 @@ void GCodeViewer::set_reduced_detail_layer_stride(unsigned int value)
|
||||
|
||||
libvgcode::EReducedDetailMode GCodeViewer::reduced_detail_mode_from_string(const std::string& mode)
|
||||
{
|
||||
if (mode == "full")
|
||||
return libvgcode::EReducedDetailMode::Off;
|
||||
if (mode == "layers")
|
||||
return libvgcode::EReducedDetailMode::LayersOnly;
|
||||
if (mode == "shell")
|
||||
|
||||
@@ -234,6 +234,7 @@ private:
|
||||
bool m_reduced_detail_while_dragging{ false };
|
||||
libvgcode::EReducedDetailMode m_reduced_detail_mode{ libvgcode::EReducedDetailMode::NoInternalInfill };
|
||||
unsigned int m_reduced_detail_layer_stride{ 4 };
|
||||
libvgcode::EReducedDetailMode m_rest_detail_mode{ libvgcode::EReducedDetailMode::Off };
|
||||
void apply_reduced_detail_settings();
|
||||
|
||||
float m_legend_height;
|
||||
@@ -352,6 +353,8 @@ public:
|
||||
// the preference's string value: "layers", "no_infill" or "shell"
|
||||
void set_reduced_detail_mode(const std::string& mode);
|
||||
void set_reduced_detail_layer_stride(unsigned int value);
|
||||
// what is left out even at rest: "full", "no_infill" or "shell"
|
||||
void set_rest_detail_mode(const std::string& mode);
|
||||
static libvgcode::EReducedDetailMode reduced_detail_mode_from_string(const std::string& mode);
|
||||
|
||||
void set_layers_z_range(const std::array<unsigned int, 2>& layers_z_range);
|
||||
|
||||
@@ -2016,6 +2016,30 @@ void PreferencesDialog::create_items()
|
||||
);
|
||||
g_sizer->Add(item_reduced_detail_layer_stride);
|
||||
|
||||
auto item_rest_detail_mode = create_item_combobox(
|
||||
_L("Always leave out"),
|
||||
_L("What the preview leaves out at all times, dragging or not, with every layer drawn. "
|
||||
"Use it when a plate of large objects is slow to draw even when the view is not moving.\n"
|
||||
"Nothing: the full preview.\n"
|
||||
"Internal infill: sparse and solid infill hidden inside the walls is left out.\n"
|
||||
"Everything but the shell: only the toolpaths on the visible surface of the print are drawn. "
|
||||
"Holes narrower than 5 mm are treated as solid."),
|
||||
"preview_rest_detail_mode",
|
||||
{_L("Nothing"), _L("Internal infill"), _L("Everything but the shell")},
|
||||
{"full", "no_infill", "shell"},
|
||||
// ORCA: apply the new mode immediately to the currently loaded preview
|
||||
[](std::string value) {
|
||||
if (Plater* plater = wxGetApp().plater()) {
|
||||
if (GLCanvas3D* canvas = plater->get_preview_canvas3D()) {
|
||||
canvas->get_gcode_viewer().set_rest_detail_mode(value);
|
||||
canvas->set_as_dirty();
|
||||
canvas->request_extra_frame();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
g_sizer->Add(item_rest_detail_mode);
|
||||
|
||||
auto item_dim_previous_layers = create_item_checkbox(
|
||||
_L("Dim lower layers"),
|
||||
_L("When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."),
|
||||
|
||||
Reference in New Issue
Block a user