mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-16 21:42:43 +00:00
Draw the Preview From a Reduced Toolpath Set While the User Is Dragging
The preview's frame cost is linear in the number of visible segments and nothing else: at 46 % of the layers the frame is 45 % of the time. A tall wipe tower puts enough segments on screen that dragging the camera or a slider cannot keep up, and no amount of shaving per-segment work fixes that - only drawing fewer segments does. Everything cheaper was measured first and ruled out. Of the remaining frame, 31 % is vertex shading and 69 % is triangle setup, so both halves scale with segment count. Screen-space decimation is useless here: the median extrusion segment is 2.5 mm and only 0.4 % are sub-pixel at full-plate zoom, so a threshold small enough to be invisible removes nothing. Merging collinear runs is no better - 2.6 % of this print's moves are collinear with the one before. So the reduction has to be one the user can see, which means it only happens while they are dragging, and only if they ask for it. update_enabled_entities() already walks every vertex to decide what is visible; it now fills a second pair of index buffers in the same walk, dropping the interior infill roles and keeping one layer in four. Because both sets are built together, switching between them is a buffer binding - no rebuild, no per-frame CPU work, which is what made occlusion culling unattractive. GLCanvas3D flips the flag while the mouse is down on the canvas or either slider is live, and asks for one more frame when the level changes so the full-detail frame lands on release. The top of the visible layer range is always kept whole: it is the surface being looked at, and the only layer drawn at full colour in top-layer-only mode. On the 636-layer, 351k-vertex three-filament fixture the set drops from 448467 segments to 85661 (19 %), and a frame during a drag goes from 298 ms to 52 ms. Off by default, behind Preferences > Graphics > G-code Preview. With it off the preview is pixel identical to before, and with it on the preview at rest is pixel identical to the preview with it off - the reduced set is only ever bound mid-drag. Verified both, plus that releasing the mouse restores full detail at an unchanged camera. The OpenGL ES path keeps a single set of entities and is untouched.
This commit is contained in:
@@ -1173,6 +1173,7 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
|
||||
m_viewer.toggle_top_layer_only_view_range();
|
||||
|
||||
// ORCA: darken the layers the preview layer slider is not scrubbed to
|
||||
m_reduced_detail_while_dragging = get_app_config()->get_bool("preview_reduced_detail_while_dragging");
|
||||
m_viewer.set_dim_previous_layers(get_app_config()->get_bool("preview_dim_previous_layers"));
|
||||
m_viewer.set_dim_previous_layers_brightness(0.01f * std::stoi(get_app_config()->get("preview_dim_previous_layers_brightness")));
|
||||
|
||||
@@ -1907,6 +1908,15 @@ void GCodeViewer::update_layers_slider_mode()
|
||||
// TODO m_layers_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder);
|
||||
}
|
||||
|
||||
bool GCodeViewer::set_interacting(bool interacting)
|
||||
{
|
||||
const bool reduced = m_reduced_detail_while_dragging && interacting;
|
||||
if (reduced == m_viewer.is_reduced_detail())
|
||||
return false;
|
||||
m_viewer.set_reduced_detail(reduced);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GCodeViewer::set_layers_z_range(const std::array<unsigned int, 2>& layers_z_range)
|
||||
{
|
||||
m_viewer.set_layers_view_range(static_cast<uint32_t>(layers_z_range[0]), static_cast<uint32_t>(layers_z_range[1]));
|
||||
|
||||
Reference in New Issue
Block a user