Merge branch 'main' into main

This commit is contained in:
Rodrigo Faselli
2026-09-24 09:15:04 -03:00
committed by GitHub
1644 changed files with 58496 additions and 15228 deletions
+136 -28
View File
@@ -108,6 +108,31 @@ static std::string get_view_type_string(libvgcode::EViewType view_type)
return "";
}
// ORCA: Stable, locale independent names used to persist a view type in the application config.
// Keep these in sync with the entries of libvgcode::EViewType exposed in the preview combo box.
static const std::vector<std::pair<std::string, libvgcode::EViewType>>& view_type_config_map()
{
static const std::vector<std::pair<std::string, libvgcode::EViewType>> map = {
{ "summary", libvgcode::EViewType::Summary },
{ "feature_type", libvgcode::EViewType::FeatureType },
{ "color_print", libvgcode::EViewType::ColorPrint },
{ "speed", libvgcode::EViewType::Speed },
{ "actual_speed", libvgcode::EViewType::ActualSpeed },
{ "acceleration", libvgcode::EViewType::Acceleration },
{ "jerk", libvgcode::EViewType::Jerk },
{ "height", libvgcode::EViewType::Height },
{ "width", libvgcode::EViewType::Width },
{ "volumetric_flow_rate", libvgcode::EViewType::VolumetricFlowRate },
{ "actual_volumetric_flow_rate", libvgcode::EViewType::ActualVolumetricFlowRate },
{ "layer_time_linear", libvgcode::EViewType::LayerTimeLinear },
{ "layer_time_logarithmic", libvgcode::EViewType::LayerTimeLogarithmic },
{ "fan_speed", libvgcode::EViewType::FanSpeed },
{ "temperature", libvgcode::EViewType::Temperature },
{ "pressure_advance", libvgcode::EViewType::PressureAdvance },
};
return map;
}
// Find an index of a value in a sorted vector, which is in <z-eps, z+eps>.
// Returns -1 if there is no such member.
static int find_close_layer_idx(const std::vector<double> &zs, double &z, double eps)
@@ -1100,9 +1125,7 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle)
// Default view type at first slice.
// May be overridden in load() once we know how many tools are actually used in the G-code.
m_nozzle_nums = preset_bundle ? preset_bundle->get_printer_extruder_count() : 1;
auto it = std::find(view_type_items.begin(), view_type_items.end(), libvgcode::EViewType::FeatureType);
m_view_type_sel = (it != view_type_items.end()) ? std::distance(view_type_items.begin(), it) : 0;
set_view_type(libvgcode::EViewType::FeatureType);
apply_default_view_type();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": finished");
}
@@ -1123,6 +1146,73 @@ void GCodeViewer::set_scale(float scale)
}
}
// ORCA: Preview default view type preference, see "preview_default_view_type" in the application config.
std::string GCodeViewer::view_type_to_config_name(libvgcode::EViewType type)
{
for (const auto& [name, value] : view_type_config_map()) {
if (value == type)
return name;
}
return std::string();
}
bool GCodeViewer::view_type_from_config_name(const std::string& name, libvgcode::EViewType& type)
{
for (const auto& [config_name, value] : view_type_config_map()) {
if (config_name == name) {
type = value;
return true;
}
}
return false;
}
std::vector<std::pair<std::string, std::string>> GCodeViewer::default_view_type_choices()
{
std::vector<std::pair<std::string, std::string>> choices = {
{ "auto", _u8L("Automatic") },
{ "last", _u8L("Last used") },
};
for (const auto& [name, type] : view_type_config_map())
choices.push_back({ name, get_view_type_string(type) });
return choices;
}
void GCodeViewer::select_view_type(libvgcode::EViewType type)
{
auto it = std::find(view_type_items.begin(), view_type_items.end(), type);
m_view_type_sel = (it != view_type_items.end()) ? static_cast<int>(std::distance(view_type_items.begin(), it)) : 0;
set_view_type(type);
}
// ORCA: Pick the view type the preview opens with, following the "preview_default_view_type" preference:
// a fixed view type, the one the user picked last ("last"), or the automatic choice ("auto", the default)
// which shows Filament for multi material prints and Line Type for single material ones.
// The default is only (re)applied when it actually changes, so a view type picked by hand survives a reslice.
void GCodeViewer::apply_default_view_type()
{
const std::string preference = wxGetApp().app_config->get("preview_default_view_type");
std::string key = preference;
libvgcode::EViewType type = libvgcode::EViewType::FeatureType;
if (preference == "last") {
if (!view_type_from_config_name(wxGetApp().app_config->get("preview_last_view_type"), type))
type = libvgcode::EViewType::FeatureType;
}
else if (!view_type_from_config_name(preference, type)) {
// "auto", or an unknown value written by a newer version
const bool multi_material = m_viewer.get_used_extruders_count() > 1;
type = multi_material ? libvgcode::EViewType::ColorPrint : libvgcode::EViewType::FeatureType;
key = multi_material ? "auto_multi_material" : "auto_single_material";
}
if (m_applied_default_view_type_key == key)
return;
m_applied_default_view_type_key = key;
select_view_type(type);
}
void GCodeViewer::update_by_mode(ConfigOptionMode mode)
{
view_type_items.clear();
@@ -1404,27 +1494,8 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
// load_toolpaths(gcode_result, build_volume, exclude_bounding_box);
// ORCA: Apply smart default view type when extruder count changes.
// Multi-color: ColorPrint (Filament), Single-color: FeatureType (Line Type).
// User selections persist within same extruder count, defaults reapply on count change.
int current_count = m_viewer.get_used_extruders_count();
if (current_count > 1) {
if (m_last_extruder_count_default_applied != 2) {
auto it = std::find(view_type_items.begin(), view_type_items.end(), libvgcode::EViewType::ColorPrint);
if (it != view_type_items.end())
m_view_type_sel = std::distance(view_type_items.begin(), it);
set_view_type(libvgcode::EViewType::ColorPrint);
m_last_extruder_count_default_applied = 2;
}
} else {
if (m_last_extruder_count_default_applied != 1) {
auto it = std::find(view_type_items.begin(), view_type_items.end(), libvgcode::EViewType::FeatureType);
if (it != view_type_items.end())
m_view_type_sel = std::distance(view_type_items.begin(), it);
set_view_type(libvgcode::EViewType::FeatureType);
m_last_extruder_count_default_applied = 1;
}
}
// ORCA: Apply the default view type now that we know how many tools the G-code actually uses.
apply_default_view_type();
// BBS: data for rendering color arrangement recommendation
m_nozzle_nums = print.config().option<ConfigOptionFloats>("nozzle_diameter")->values.size();
@@ -1851,7 +1922,7 @@ void GCodeViewer::render_scene(int canvas_width, int canvas_height)
glsafe(::glEnable(GL_DEPTH_TEST));
render_shells(canvas_width, canvas_height);
if (m_viewer.get_extrusion_roles().empty())
if (m_viewer.get_extrusion_roles_count() == 0)
return;
render_toolpaths();
@@ -2046,6 +2117,29 @@ void GCodeViewer::render_scene(int canvas_width, int canvas_height)
}
}
void GCodeViewer::render_shadow_casters(const Transform3d& light_view_matrix, const Transform3d& light_projection_matrix, const Vec3d& light_position)
{
if (!has_data())
return;
m_viewer.render_shadow_casters(
libvgcode::convert(static_cast<Matrix4f>(light_view_matrix.matrix().cast<float>())),
libvgcode::convert(static_cast<Matrix4f>(light_projection_matrix.matrix().cast<float>())),
libvgcode::convert(static_cast<Vec3f>(light_position.cast<float>())));
}
void GCodeViewer::set_shadow_map(int texture_unit, const Transform3d& light_view_projection, float intensity, float texel_size)
{
m_viewer.set_shadow_map(texture_unit,
libvgcode::convert(static_cast<Matrix4f>(light_view_projection.matrix().cast<float>())),
intensity, texel_size);
}
void GCodeViewer::set_tone(float exposure, float saturation)
{
m_viewer.set_tone(exposure, saturation);
}
void GCodeViewer::render_overlay(int canvas_width, int canvas_height, int right_margin)
{
if (m_viewer.get_extrusion_roles().empty())
@@ -3832,6 +3926,12 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
std::vector<std::pair<ColorRGBA, std::pair<double, double>>> ret;
ret.reserve(custom_gcode_per_print_z.size());
// Loop invariant, but built lazily: this lambda runs once per extruder on every frame
// and most prints reach neither colour change below, so fetching it up front would cost
// more than the per-item fetch it replaces.
std::vector<float> zs;
bool zs_built = false;
for (const auto& item : custom_gcode_per_print_z) {
if (extruder_id + 1 != static_cast<unsigned char>(item.extruder))
continue;
@@ -3839,7 +3939,10 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
if (item.type != ColorChange)
continue;
const std::vector<float> zs = m_viewer.get_layers_zs();
if (!zs_built) {
zs = m_viewer.get_layers_zs();
zs_built = true;
}
auto lower_b = std::lower_bound(zs.begin(), zs.end(),
static_cast<float>(item.print_z - epsilon()));
if (lower_b == zs.end())
@@ -3964,6 +4067,10 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
m_view_type_sel = i;
set_view_type(view_type_items[m_view_type_sel]);
reset_visible(view_type_items[m_view_type_sel]);
// ORCA: remember the pick so the "Last used" preview default can restore it
const std::string view_type_name = view_type_to_config_name(view_type_items[m_view_type_sel]);
if (!view_type_name.empty())
wxGetApp().app_config->set("preview_last_view_type", view_type_name);
update_moves_slider();
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
imgui.set_requires_extra_frame();
@@ -4988,6 +5095,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
// ORCA: Get layer Zs as doubles
std::vector<double> layer_zs = get_layers_zs();
// loop invariant, same reason as the layer Zs above
const std::vector<float> layer_times = m_viewer.get_layers_estimated_times();
for (Slic3r::CustomGCode::Item custom_gcode : custom_gcode_per_print_z) {
ImGui::Dummy({window_padding, window_padding});
@@ -5007,7 +5116,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
imgui.text(buf);
ImGui::SameLine(max_len * 1.5);
std::vector<float> layer_times = m_viewer.get_layers_estimated_times();
float custom_gcode_time = 0;
if (layer > 0)
{
@@ -5056,7 +5164,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
std::string print_str = _u8L("Model printing time");
std::string total_str = _u8L("Total time");
float max_len = window_padding + 2 * ImGui::GetStyle().ItemSpacing.x;
if (m_viewer.get_layers_estimated_times().empty())
if (m_viewer.get_layers_count() == 0)
max_len += ImGui::CalcTextSize(total_str.c_str()).x;
else {
if (m_viewer.get_view_type() == libvgcode::EViewType::FeatureType)