mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-19 21:51:06 +00:00
Part 2.5: Add global shear transform, support clipping, and belt UI improvements
- Implement per-object global shear transform in PrintObject with layer Z-offset calculation, config invalidation, and fix for shared-object layer optimization breaking copied objects - Clip support layers to the transformed belt floor plane and begin work on tree support adaptation for sheared coordinate space - Improve belt UI: gray out inactive sub-options, add B keyboard shortcut for G-code viewer design-view toggle, fix mesh clipping through build plate after shear/scale transform y' = y + z·cot(α), while x' = x and z' = z getting closer to customizable variant getting closer X/Y/Z shear initial clean up UI add 1/sin(a) transform, idea taken from blackbelt cura plugin Things work now (turns out I've been using the wrong set of transforms)
This commit is contained in:
1 parent
501aff7e53
commit
98f4d34dcb
13 files changed
+452
-91
No files matched your search
@@ -1271,7 +1271,7 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
|
||||
|
||||
m_max_print_height = gcode_result.printable_height;
|
||||
m_z_offset = gcode_result.z_offset;
|
||||
m_belt_z_shift = gcode_result.belt_z_shift;
|
||||
|
||||
|
||||
// load_toolpaths(gcode_result, build_volume, exclude_bounding_box);
|
||||
|
||||
@@ -2210,15 +2210,17 @@ void GCodeViewer::render_toolpaths()
|
||||
{
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Matrix4f view = camera.get_view_matrix().matrix().cast<float>();
|
||||
// Belt "raw" view: apply slicing rotation to view matrix so toolpaths appear
|
||||
// in the slicing frame (rotated part with horizontal layers).
|
||||
if (m_belt_show_raw && m_belt_view_enabled && m_belt_angle_deg > 0.f) {
|
||||
// Belt "designed" view: apply inverse shear to view matrix so toolpaths appear
|
||||
// upright (as originally designed) instead of sheared on the belt.
|
||||
if (m_belt_show_designed && m_belt_view_enabled && m_belt_angle_deg > 0.f) {
|
||||
double angle_rad = Geometry::deg2rad(static_cast<double>(m_belt_angle_deg));
|
||||
// Apply R(-alpha, X) * T(0,0,-z_shift) to bring machine coords back to slicing frame.
|
||||
Transform3d slicing_trafo = Transform3d::Identity();
|
||||
slicing_trafo.translate(Vec3d(0., 0., -static_cast<double>(m_belt_z_shift)));
|
||||
slicing_trafo = Eigen::AngleAxisd(-angle_rad, Vec3d::UnitX()) * slicing_trafo;
|
||||
view = (camera.get_view_matrix() * slicing_trafo).matrix().cast<float>();
|
||||
double sin_a = std::sin(angle_rad);
|
||||
if (sin_a > 1e-6) {
|
||||
double cot_alpha = std::cos(angle_rad) / sin_a;
|
||||
Transform3d inverse_shear = Transform3d::Identity();
|
||||
inverse_shear.matrix()(1, 2) = -cot_alpha; // Y -= Z * cot(α)
|
||||
view = (camera.get_view_matrix() * inverse_shear).matrix().cast<float>();
|
||||
}
|
||||
}
|
||||
const libvgcode::Mat4x4 converted_view_matrix = libvgcode::convert(view);
|
||||
const libvgcode::Mat4x4 converted_projetion_matrix = libvgcode::convert(static_cast<Matrix4f>(camera.get_projection_matrix().matrix().cast<float>()));
|
||||
@@ -4421,7 +4423,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
ImGui::Spacing();
|
||||
ImGui::Dummy({ window_padding, 0 });
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Show raw G-code (slicing frame)", &m_belt_show_raw);
|
||||
ImGui::Checkbox("Show designed view (upright)", &m_belt_show_designed);
|
||||
}
|
||||
|
||||
legend_height = ImGui::GetCurrentWindow()->Size.y;
|
||||
|
||||
@@ -239,8 +239,7 @@ mutable bool m_no_render_path { false };
|
||||
|
||||
bool m_belt_view_enabled = false;
|
||||
float m_belt_angle_deg = 0.f;
|
||||
float m_belt_z_shift = 0.f;
|
||||
bool m_belt_show_raw = false; // Toggle: show raw slicing-frame G-code (rotated part)
|
||||
bool m_belt_show_designed = false; // Toggle: show designed (upright) view via inverse shear
|
||||
|
||||
libvgcode::Viewer m_viewer;
|
||||
bool m_loaded_as_preview{ false };
|
||||
|
||||
@@ -4370,6 +4370,53 @@ void TabPrinter::build_fff()
|
||||
optgroup->append_single_option_line("belt_printer");
|
||||
optgroup->append_single_option_line("belt_printer_angle");
|
||||
optgroup->append_single_option_line("belt_printer_infinite_y");
|
||||
// Per-axis shear: group mode + angle + source on one row per axis
|
||||
{
|
||||
Line line = { L("Shear X"), L("Shear applied to the X axis before slicing") };
|
||||
line.append_option(optgroup->get_option("belt_shear_x"));
|
||||
line.append_option(optgroup->get_option("belt_shear_x_angle"));
|
||||
line.append_option(optgroup->get_option("belt_shear_x_from"));
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
{
|
||||
Line line = { L("Shear Y"), L("Shear applied to the Y axis before slicing") };
|
||||
line.append_option(optgroup->get_option("belt_shear_y"));
|
||||
line.append_option(optgroup->get_option("belt_shear_y_angle"));
|
||||
line.append_option(optgroup->get_option("belt_shear_y_from"));
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
{
|
||||
Line line = { L("Shear Z"), L("Shear applied to the Z axis before slicing") };
|
||||
line.append_option(optgroup->get_option("belt_shear_z"));
|
||||
line.append_option(optgroup->get_option("belt_shear_z_angle"));
|
||||
line.append_option(optgroup->get_option("belt_shear_z_from"));
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
{
|
||||
Line line = { L("Scale X"), L("Scale applied to the X axis before slicing") };
|
||||
line.append_option(optgroup->get_option("belt_scale_x"));
|
||||
line.append_option(optgroup->get_option("belt_scale_x_angle"));
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
{
|
||||
Line line = { L("Scale Y"), L("Scale applied to the Y axis before slicing") };
|
||||
line.append_option(optgroup->get_option("belt_scale_y"));
|
||||
line.append_option(optgroup->get_option("belt_scale_y_angle"));
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
{
|
||||
Line line = { L("Scale Z"), L("Scale applied to the Z axis before slicing") };
|
||||
line.append_option(optgroup->get_option("belt_scale_z"));
|
||||
line.append_option(optgroup->get_option("belt_scale_z_angle"));
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
{
|
||||
Line line = { L("G-code axis remap"), L("Remap slicing-frame axes to machine axes in G-code output") };
|
||||
line.append_option(optgroup->get_option("belt_gcode_remap_x"));
|
||||
line.append_option(optgroup->get_option("belt_gcode_remap_y"));
|
||||
line.append_option(optgroup->get_option("belt_gcode_remap_z"));
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
optgroup->append_single_option_line("support_multi_bed_types","printer_basic_information_printable_space#support-multi-bed-types");
|
||||
optgroup->append_single_option_line("best_object_pos", "printer_basic_information_printable_space#best-object-position");
|
||||
// todo: for multi_extruder test
|
||||
@@ -5233,6 +5280,10 @@ void TabPrinter::toggle_options()
|
||||
bool is_belt = m_config->opt_bool("belt_printer");
|
||||
toggle_line("belt_printer_angle", is_belt);
|
||||
toggle_line("belt_printer_infinite_y", is_belt);
|
||||
for (auto el : {"belt_shear_x", "belt_shear_y", "belt_shear_z",
|
||||
"belt_scale_x", "belt_scale_y", "belt_scale_z",
|
||||
"belt_gcode_remap_x"})
|
||||
toggle_line(el, is_belt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user