mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-02 05:11:00 +00:00
Add a Shell-Only Drag Mode That Keeps What Can Be Seen From Outside
A third mode of the drag preference: the reduced set keeps every role but the sparse infill, internal solid infill, internal bridge infill and gap fill, which lie under the skins or between the walls, on every layer. Walls, top and bottom surfaces, bridges, supports and the prime tower are drawn whole, so from outside the print looks as it does at rest, and the two end layers of the visible range stay whole as in every mode. The roles come from the slicer, so the classification is exact wherever the slicer's is. What a role cannot tell apart is the inside of the prime tower or of a support from its outside; both are kept whole. A profile with no top or bottom shell layers exposes infill, which this mode hides.
This commit is contained in:
@@ -9,8 +9,8 @@ let go.
|
||||
|
||||
| Preference | Values | Effect |
|
||||
|---|---|---|
|
||||
| `preview_reduced_detail_mode` | `off`, `solid`, `layers`, `outer_walls` | what is drawn while dragging |
|
||||
| `preview_reduced_detail_layer_stride` | 1–20 | one layer in every N is kept by the toolpath modes |
|
||||
| `preview_reduced_detail_mode` | `off`, `solid`, `layers`, `outer_walls`, `shell` | what is drawn while dragging |
|
||||
| `preview_reduced_detail_layer_stride` | 1–20 | one layer in every N is kept by the skip-layers and outer-walls modes |
|
||||
|
||||
libvgcode (`src/libvgcode`) builds and binds the reduced toolpath set, `GCodeViewer` maps the
|
||||
preferences onto it and draws the solid model, and `GLCanvas3D` decides when the user is dragging.
|
||||
@@ -35,6 +35,13 @@ are the faces the range cuts open, and the top is what the user is looking at.
|
||||
- `LayersOnly` (`layers`) keeps every role of one layer in every stride.
|
||||
- `OuterWallsOnly` (`outer_walls`) keeps the outer and overhang perimeters of one layer in every
|
||||
stride. The prime tower and supports have other roles and are left out.
|
||||
- `ShellOnly` (`shell`) keeps every layer, and every role but the sparse infill, internal solid
|
||||
infill, internal bridge infill and gap fill, which lie under the skins or between the walls.
|
||||
Walls, top and bottom surfaces, bridges, supports and the prime tower are drawn whole, so from
|
||||
outside the print looks as it does at rest, and the stride does not apply. The roles come from
|
||||
the slicer, so the classification is exact wherever the slicer's is; what it cannot express is
|
||||
the inside of the prime tower and of a support, which share one role with their outside and are
|
||||
kept whole. A profile with no top or bottom shell layers exposes infill, which this mode hides.
|
||||
|
||||
## The solid model
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ void AppConfig::set_defaults()
|
||||
// what the preview draws while the user drags it, and one layer in how many the toolpath modes keep
|
||||
{
|
||||
const std::string mode = get("preview_reduced_detail_mode");
|
||||
if (mode != "off" && mode != "solid" && mode != "layers" && mode != "outer_walls")
|
||||
if (mode != "off" && mode != "solid" && mode != "layers" && mode != "outer_walls" && mode != "shell")
|
||||
set("preview_reduced_detail_mode", "off");
|
||||
int stride = 4;
|
||||
try {
|
||||
|
||||
@@ -172,6 +172,8 @@ enum class EReducedDetailMode : uint8_t
|
||||
LayersOnly,
|
||||
// one layer in every stride, outer walls only
|
||||
OuterWallsOnly,
|
||||
// every layer, every role but the infill under the skins and the gap fill: what can be seen from outside
|
||||
ShellOnly,
|
||||
COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
#include <cfloat>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
@@ -1194,17 +1195,34 @@ void ViewerImpl::load(GCodeInputData&& gcode_data)
|
||||
}
|
||||
|
||||
#ifndef ENABLE_OPENGL_ES
|
||||
static bool is_outer_wall(EGCodeExtrusionRole role)
|
||||
{
|
||||
return role == EGCodeExtrusionRole::ExternalPerimeter || role == EGCodeExtrusionRole::OverhangPerimeter;
|
||||
}
|
||||
|
||||
// the roles that lie under a skin or between walls, never seen from outside the print
|
||||
static bool is_hidden_in_shell(EGCodeExtrusionRole role)
|
||||
{
|
||||
return role == EGCodeExtrusionRole::InternalInfill ||
|
||||
role == EGCodeExtrusionRole::SolidInfill ||
|
||||
role == EGCodeExtrusionRole::InternalBridgeInfill ||
|
||||
role == EGCodeExtrusionRole::GapFill;
|
||||
}
|
||||
|
||||
bool ViewerImpl::reduced_set_keeps(const PathVertex& v) const
|
||||
{
|
||||
switch (m_settings.reduced_detail_mode) {
|
||||
case EReducedDetailMode::OuterWallsOnly:
|
||||
return v.role == EGCodeExtrusionRole::ExternalPerimeter || v.role == EGCodeExtrusionRole::OverhangPerimeter;
|
||||
return is_outer_wall(v.role);
|
||||
case EReducedDetailMode::ShellOnly:
|
||||
return !is_hidden_in_shell(v.role);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
|
||||
void ViewerImpl::update_enabled_entities()
|
||||
{
|
||||
if (m_vertices.empty())
|
||||
@@ -1222,6 +1240,8 @@ void ViewerImpl::update_enabled_entities()
|
||||
std::vector<uint32_t> enabled_segments_reduced;
|
||||
std::vector<uint32_t> enabled_options_reduced;
|
||||
const Interval& layers_range = m_layers.get_view_range();
|
||||
// the shell mode draws every layer, the other toolpath modes one in every stride
|
||||
const bool shell_reduced = reduced_mode == EReducedDetailMode::ShellOnly;
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
Interval range = m_view_range.get_visible();
|
||||
|
||||
@@ -1276,7 +1296,7 @@ void ViewerImpl::update_enabled_entities()
|
||||
const bool end_layer = v.layer_id == layers_range[0] || v.layer_id == layers_range[1];
|
||||
if (end_layer)
|
||||
(v.is_option() ? enabled_options_reduced : enabled_segments_reduced).push_back(static_cast<uint32_t>(i));
|
||||
else if (reduced_mode != EReducedDetailMode::EndLayersOnly && (v.layer_id % layer_stride) == 0) {
|
||||
else if (reduced_mode != EReducedDetailMode::EndLayersOnly && (shell_reduced || (v.layer_id % layer_stride) == 0)) {
|
||||
if (v.is_option())
|
||||
enabled_options_reduced.push_back(static_cast<uint32_t>(i));
|
||||
else if (!v.is_extrusion() || reduced_set_keeps(v))
|
||||
|
||||
@@ -537,7 +537,7 @@ private:
|
||||
|
||||
// The set the next draw reads from: the reduced one while dragging, if one is built.
|
||||
bool use_reduced_set() const { return m_settings.reduced_detail && m_settings.reduced_detail_mode != EReducedDetailMode::Off; }
|
||||
// Whether an extrusion segment belongs to the reduced set under the current mode
|
||||
// Whether the extrusion segment starting at vertex v belongs to the reduced set under the current mode
|
||||
bool reduced_set_keeps(const PathVertex& v) const;
|
||||
struct ActiveSet
|
||||
{
|
||||
|
||||
@@ -2069,6 +2069,8 @@ libvgcode::EReducedDetailMode GCodeViewer::reduced_detail_mode_from_string(const
|
||||
return libvgcode::EReducedDetailMode::LayersOnly;
|
||||
if (mode == "outer_walls")
|
||||
return libvgcode::EReducedDetailMode::OuterWallsOnly;
|
||||
if (mode == "shell")
|
||||
return libvgcode::EReducedDetailMode::ShellOnly;
|
||||
return libvgcode::EReducedDetailMode::Off;
|
||||
}
|
||||
|
||||
|
||||
@@ -382,7 +382,7 @@ public:
|
||||
// while the user drags the camera or a slider, draw the reduced set, if the preference asks for one
|
||||
void set_interacting(bool interacting);
|
||||
bool is_reduced_detail() const { return m_viewer.is_reduced_detail(); }
|
||||
// the preference's string value: "off", "solid", "layers" or "outer_walls"
|
||||
// the preference's string value: "off", "solid", "layers", "outer_walls" or "shell"
|
||||
void set_reduced_detail_mode(const std::string& mode);
|
||||
void set_reduced_detail_layer_stride(unsigned int value);
|
||||
|
||||
|
||||
@@ -2065,10 +2065,12 @@ void PreferencesDialog::create_items()
|
||||
"with its bottom and top layers drawn as toolpaths. Supports are not shown, and negative volumes are not cut out.\n"
|
||||
"Skip layers: the toolpaths of one layer in every N, set below.\n"
|
||||
"Outer walls: only the outer walls of one layer in every N. The prime tower and supports are left out.\n"
|
||||
"Shell only: every layer without its sparse infill, internal solid infill and gap fill, which lie under the walls and skins. "
|
||||
"Walls, top and bottom surfaces, bridges, supports and the prime tower are drawn whole, so the print looks the same from outside.\n"
|
||||
"The bottom and top of the visible layer range are always drawn whole."),
|
||||
"preview_reduced_detail_mode",
|
||||
{_L("Off"), _L("Solid model"), _L("Skip layers"), _L("Outer walls")},
|
||||
{"off", "solid", "layers", "outer_walls"},
|
||||
{_L("Off"), _L("Solid model"), _L("Skip layers"), _L("Outer walls"), _L("Shell only")},
|
||||
{"off", "solid", "layers", "outer_walls", "shell"},
|
||||
// apply the new mode immediately to the currently loaded preview
|
||||
[this](std::string value) {
|
||||
if (m_reduced_detail_layer_stride_input)
|
||||
|
||||
Reference in New Issue
Block a user