mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-14 20:47:33 +00:00
Offer the Sliced Objects as a Solid Model While Dragging
The reductions built for dragging still draw toolpaths, and a plate of large objects has many even one layer in four. The objects themselves are cheaper: a mesh costs its triangles once, and the preview already loads the objects as shells for its translucent ghost. So the Simplification choice gains a fourth entry, Solid model, that draws the shells opaque in their filament colours instead of the toolpaths while the user drags. The visible layer range still holds. The shells are cut at the range's top and bottom through the shader's z range, and the toolpath set bound while dragging keeps just those two layers, drawn afterwards so that they cap the cut with what was really printed there. The prime tower is added to the shells from its sliced mesh, positioned as the print placed it; it keeps its opaque colour and so stays out of the translucent ghost. Supports have no mesh and are not shown in this mode, which the preference text says. Verified on the tall fixture and on a nine-cube plate: mid-drag the objects and the tower are solids capped by their top layer, cut to a shortened layer range, and with the preference off the preview is pixel identical to before.
This commit is contained in:
@@ -208,7 +208,7 @@ void AppConfig::set_defaults()
|
||||
|
||||
{
|
||||
const std::string mode = get("preview_reduced_detail_mode");
|
||||
if (mode != "layers" && mode != "no_infill" && mode != "shell")
|
||||
if (mode != "layers" && mode != "no_infill" && mode != "shell" && mode != "solid")
|
||||
set("preview_reduced_detail_mode", "no_infill");
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,9 @@ enum class EReducedDetailMode : uint8_t
|
||||
NoInternalInfill,
|
||||
// only the segments on the visible surface of the print are kept
|
||||
ShellOnly,
|
||||
// only the bottom and top of the visible layer range are kept, for a caller that draws the
|
||||
// print itself some other way and needs just the two faces the range cuts open
|
||||
EndLayersOnly,
|
||||
COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -1779,6 +1779,11 @@ void ViewerImpl::update_enabled_entities()
|
||||
}
|
||||
if (!build_reduced)
|
||||
continue;
|
||||
if (m_settings.reduced_detail_mode == EReducedDetailMode::EndLayersOnly) {
|
||||
if (whole_layer)
|
||||
(v.is_option() ? enabled_options_reduced : enabled_segments_reduced).push_back(static_cast<uint32_t>(i));
|
||||
continue;
|
||||
}
|
||||
if (!whole_layer && (v.layer_id % layer_stride) != 0) {
|
||||
// the surfaces of a skipped layer that either side can see stay, so that a step does not vanish
|
||||
if (shell_reduced && (visible_from_above || visible_from_below))
|
||||
|
||||
@@ -565,7 +565,7 @@ private:
|
||||
bool use_rest_set() const { return !use_reduced_set() && build_rest_set(); }
|
||||
// how many layers each drawn segment of the bound set stands in for
|
||||
float active_height_scale() const {
|
||||
if (use_reduced_set())
|
||||
if (use_reduced_set() && m_settings.reduced_detail_mode != EReducedDetailMode::EndLayersOnly)
|
||||
return static_cast<float>(std::max<uint32_t>(1, m_settings.reduced_detail_layer_stride));
|
||||
if (use_rest_set() && m_settings.rest_detail_mode == EReducedDetailMode::ShellOnly)
|
||||
return static_cast<float>(std::max<uint32_t>(1, m_settings.rest_layer_stride));
|
||||
|
||||
@@ -1175,6 +1175,7 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
|
||||
// ORCA: simplify the preview while the user is dragging
|
||||
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_solid_model_while_dragging = m_reduced_detail_mode == libvgcode::EReducedDetailMode::EndLayersOnly;
|
||||
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();
|
||||
@@ -1653,8 +1654,15 @@ void GCodeViewer::reset()
|
||||
void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin, bool draw_scene)
|
||||
{
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
if (draw_scene)
|
||||
render_shells(canvas_width, canvas_height);
|
||||
// while dragging in the solid model mode the objects stand in for their toolpaths, cut to the
|
||||
// visible layer range; the toolpath set then holds only the range's bottom and top layers
|
||||
const bool solid_model = m_interacting && m_solid_model_while_dragging && m_viewer.is_reduced_detail();
|
||||
if (draw_scene) {
|
||||
if (solid_model)
|
||||
render_solid_model(canvas_width, canvas_height);
|
||||
else
|
||||
render_shells(canvas_width, canvas_height);
|
||||
}
|
||||
|
||||
if (m_viewer.get_extrusion_roles_count() == 0)
|
||||
return;
|
||||
@@ -2007,6 +2015,7 @@ void GCodeViewer::set_reduced_detail_while_dragging(bool value)
|
||||
void GCodeViewer::set_reduced_detail_mode(const std::string& mode)
|
||||
{
|
||||
m_reduced_detail_mode = reduced_detail_mode_from_string(mode);
|
||||
m_solid_model_while_dragging = m_reduced_detail_mode == libvgcode::EReducedDetailMode::EndLayersOnly;
|
||||
apply_reduced_detail_settings();
|
||||
}
|
||||
|
||||
@@ -2020,6 +2029,8 @@ libvgcode::EReducedDetailMode GCodeViewer::reduced_detail_mode_from_string(const
|
||||
{
|
||||
if (mode == "full")
|
||||
return libvgcode::EReducedDetailMode::Off;
|
||||
if (mode == "solid")
|
||||
return libvgcode::EReducedDetailMode::EndLayersOnly;
|
||||
if (mode == "layers")
|
||||
return libvgcode::EReducedDetailMode::LayersOnly;
|
||||
if (mode == "shell")
|
||||
@@ -2415,6 +2426,19 @@ void GCodeViewer::load_shells(const Print& print, bool initialized, bool force_p
|
||||
object_count++;
|
||||
}
|
||||
|
||||
// the prime tower as it was sliced, so that the solid model shows what the print shows; it
|
||||
// keeps its opaque colour and so never appears among the translucent shells
|
||||
if (print.is_step_done(psWipeTower) && print.wipe_tower_data().wipe_tower_mesh_data) {
|
||||
const PrintConfig& config = print.config();
|
||||
const int plate_idx = print.get_plate_index();
|
||||
const Vec3d plate_origin = print.get_plate_origin();
|
||||
const float x = static_cast<float>(config.wipe_tower_x.get_at(plate_idx) + plate_origin.x());
|
||||
const float y = static_cast<float>(config.wipe_tower_y.get_at(plate_idx) + plate_origin.y());
|
||||
m_shells.volumes.load_real_wipe_tower_preview(1000, x, y, print.wipe_tower_data().wipe_tower_mesh_data->real_wipe_tower_mesh,
|
||||
print.wipe_tower_data().wipe_tower_mesh_data->real_brim_mesh, true,
|
||||
static_cast<float>(config.wipe_tower_rotation_angle), false, initialized);
|
||||
}
|
||||
|
||||
// Orca: disable wipe tower shell
|
||||
// if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF) {
|
||||
// // BBS: adds wipe tower's volume
|
||||
@@ -2665,6 +2689,47 @@ void GCodeViewer::render_shells(int canvas_width, int canvas_height)
|
||||
glsafe(::glDepthMask(GL_TRUE));
|
||||
}
|
||||
|
||||
// The sliced objects and the prime tower drawn opaque, in their filament colours, cut to the
|
||||
// visible layer range by the shader's z range. The toolpaths of the range's bottom and top layers
|
||||
// are drawn afterwards and cap the cut.
|
||||
void GCodeViewer::render_solid_model(int canvas_width, int canvas_height)
|
||||
{
|
||||
if (m_shells.volumes.empty())
|
||||
return;
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
const libvgcode::Interval& layers = m_viewer.get_layers_view_range();
|
||||
const float z_top = m_viewer.get_layer_z(layers[1]) - m_z_offset + 0.001f;
|
||||
const float z_bottom = (layers[0] > 0) ? m_viewer.get_layer_z(layers[0] - 1) - m_z_offset - 0.001f : -FLT_MAX;
|
||||
|
||||
std::vector<float> alphas;
|
||||
alphas.reserve(m_shells.volumes.volumes.size());
|
||||
for (GLVolume* volume : m_shells.volumes.volumes) {
|
||||
alphas.push_back(volume->color.a());
|
||||
volume->color.a(1.0f);
|
||||
volume->set_render_color();
|
||||
}
|
||||
m_shells.volumes.set_z_range(z_bottom, z_top);
|
||||
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("z_far", camera.get_far_z());
|
||||
shader->set_uniform("z_near", camera.get_near_z());
|
||||
m_shells.volumes.render(GLVolumeCollection::ERenderType::Opaque, false, camera.get_view_matrix(), camera.get_projection_matrix(), {canvas_width, canvas_height});
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
shader->stop_using();
|
||||
|
||||
m_shells.volumes.set_z_range(-FLT_MAX, FLT_MAX);
|
||||
size_t k = 0;
|
||||
for (GLVolume* volume : m_shells.volumes.volumes) {
|
||||
volume->color.a(alphas[k++]);
|
||||
volume->set_render_color();
|
||||
}
|
||||
}
|
||||
|
||||
//BBS
|
||||
void GCodeViewer::render_all_plates_stats(const std::vector<const GCodeProcessorResult*>& gcode_result_list, bool show /*= true*/) const {
|
||||
if (!show)
|
||||
|
||||
@@ -235,6 +235,9 @@ private:
|
||||
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 };
|
||||
// ORCA: draw the sliced objects as solid shapes instead of toolpaths while dragging
|
||||
bool m_solid_model_while_dragging{ false };
|
||||
void render_solid_model(int canvas_width, int canvas_height);
|
||||
void apply_reduced_detail_settings();
|
||||
// whether the user is dragging or a wheel burst is settling, as told by set_interacting()
|
||||
bool m_interacting{ false };
|
||||
|
||||
@@ -1977,10 +1977,12 @@ void PreferencesDialog::create_items()
|
||||
"Skip layers only: every toolpath of the drawn layers is kept.\n"
|
||||
"Skip internal infill: sparse and solid infill hidden inside the walls is left out.\n"
|
||||
"Shell only: only the toolpaths on the visible surface of the print are drawn, including the outside of the prime tower. "
|
||||
"Removes the most, and holes narrower than 5 mm are treated as solid."),
|
||||
"Removes the most of the toolpath modes, and holes narrower than 5 mm are treated as solid.\n"
|
||||
"Solid model: the sliced objects and the prime tower are drawn as solid shapes in their filament colours instead of toolpaths, "
|
||||
"cut to the visible layer range with the range's bottom and top layers drawn on top. Cheapest of all; supports are not shown, and the layer setting below does not apply."),
|
||||
"preview_reduced_detail_mode",
|
||||
{_L("Skip layers only"), _L("Skip internal infill"), _L("Shell only")},
|
||||
{"layers", "no_infill", "shell"},
|
||||
{_L("Skip layers only"), _L("Skip internal infill"), _L("Shell only"), _L("Solid model")},
|
||||
{"layers", "no_infill", "shell", "solid"},
|
||||
// ORCA: apply the new mode immediately to the currently loaded preview
|
||||
[](std::string value) {
|
||||
if (Plater* plater = wxGetApp().plater()) {
|
||||
|
||||
Reference in New Issue
Block a user