mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-15 03:41:28 +00:00
ENH: Add "Drop" button to move gizmo for objects, parts, and modifiers. And unify all Drop actions / checks (#16323)
* Add Drop to bed button for objects, parts and modifiers to the Position panel Ported from BambuStudio PR #11511. The button appears under the position inputs when the selection is not resting on the bed and moves it along global Z. Works for a single full instance as well as a single part or modifier, and is undoable. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7uDtamzhNGT6PFwmVdRJ8 * Reuse existing 'Drop to Bed' string so the button is already translated Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7uDtamzhNGT6PFwmVdRJ8 * Add tooltip to the Drop to Bed button Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7uDtamzhNGT6PFwmVdRJ8 * unify function usage across UI * Update GizmoObjectManipulation.cpp * show tooltip even its disabled * update * Update GizmoObjectManipulation.cpp * update --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: yw4z <ywsyildiz@gmail.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
yw4z
parent
70e5b330be
commit
6a7763f08d
@@ -2400,7 +2400,7 @@ void MenuFactory::append_menu_item_drop(wxMenu* menu)
|
||||
if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
|
||||
return false;
|
||||
else {
|
||||
return (std::abs(plater()->get_view3D_canvas3D()->get_selection().get_bounding_box().min.z()) > -SINKING_Z_THRESHOLD);
|
||||
return plater()->get_view3D_canvas3D()->get_selection().can_drop();
|
||||
} //disable if model is on the bed / not in View3D
|
||||
}, m_parent);
|
||||
}
|
||||
|
||||
@@ -57,24 +57,6 @@ const double GizmoObjectManipulation::mm_to_in = 0.0393700787;
|
||||
const double GizmoObjectManipulation::oz_to_g = 28.34952;
|
||||
const double GizmoObjectManipulation::g_to_oz = 0.035274;
|
||||
|
||||
// Helper function to be used by drop to bed button. Returns lowest point of this
|
||||
// volume in world coordinate system.
|
||||
static double get_volume_min_z(const GLVolume* volume)
|
||||
{
|
||||
const Transform3f& world_matrix = volume->world_matrix().cast<float>();
|
||||
|
||||
// need to get the ModelVolume pointer
|
||||
const ModelObject* mo = wxGetApp().model().objects[volume->composite_id.object_id];
|
||||
const ModelVolume* mv = mo->volumes[volume->composite_id.volume_id];
|
||||
const TriangleMesh& hull = mv->get_convex_hull();
|
||||
|
||||
float min_z = std::numeric_limits<float>::max();
|
||||
for (const stl_vertex& vert : hull.its.vertices) {
|
||||
min_z = std::min(min_z, Vec3f::UnitZ().dot(world_matrix * vert));
|
||||
}
|
||||
return min_z;
|
||||
}
|
||||
|
||||
GizmoObjectManipulation::GizmoObjectManipulation(GLCanvas3D& glcanvas)
|
||||
: m_glcanvas(glcanvas), m_alignment_helper(glcanvas)
|
||||
{
|
||||
@@ -295,12 +277,14 @@ void GizmoObjectManipulation::update_reset_buttons_visibility()
|
||||
{
|
||||
const Selection& selection = m_glcanvas.get_selection();
|
||||
|
||||
// Assembly view has its own selection and transformations, which drop_selection() doesn't update
|
||||
m_enable_drop_to_bed = m_glcanvas.get_canvas_type() == GLCanvas3D::ECanvasType::CanvasView3D && selection.can_drop();
|
||||
|
||||
if (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) {
|
||||
const GLVolume * volume = selection.get_first_volume();
|
||||
|
||||
Vec3d rotation;
|
||||
Vec3d scale;
|
||||
double min_z = 0.;
|
||||
|
||||
if (selection.is_single_full_instance()) {
|
||||
rotation = volume->get_instance_rotation();
|
||||
@@ -309,12 +293,10 @@ void GizmoObjectManipulation::update_reset_buttons_visibility()
|
||||
else {
|
||||
rotation = volume->get_volume_rotation();
|
||||
scale = volume->get_volume_scaling_factor();
|
||||
min_z = get_volume_min_z(volume);
|
||||
}
|
||||
m_show_clear_rotation = !rotation.isApprox(m_init_rotation);
|
||||
m_show_reset_0_rotation = !rotation.isApprox(Vec3d::Zero());
|
||||
m_show_clear_scale = (m_cache.scale / 100.0f - Vec3d::Ones()).norm() > 0.001;
|
||||
m_show_drop_to_bed = (std::abs(min_z) > EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1072,6 +1054,17 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper,
|
||||
|
||||
GLGizmoUtils::render_tooltip_button(imgui_wrapper, m_glcanvas, m_shortcuts_move, x, y);
|
||||
|
||||
// ORCA use existing function for drop and show button on bottom bar to keep gizmo compact
|
||||
imgui_wrapper->disabled_begin(!m_enable_drop_to_bed);
|
||||
ImGui::SameLine(0, space_size * 1.5f);
|
||||
if (imgui_wrapper->button(_L("Drop"))){
|
||||
wxGetApp().plater()->drop_selection();
|
||||
UpdateAndShow(true);
|
||||
}
|
||||
imgui_wrapper->disabled_end();
|
||||
if(ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
imgui_wrapper->tooltip(_L("Move the selection along Z so that its lowest point touches the bed."), ImGui::GetFontSize() * 20.0f);
|
||||
|
||||
ImGui::SameLine();
|
||||
GLGizmoUtils::begin_right_aligned_buttons({ _L("Done") });
|
||||
if (imgui_wrapper->button(_L("Done"))) {
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
bool m_show_reset_0_rotation{false};
|
||||
bool m_show_clear_rotation { false };
|
||||
bool m_show_clear_scale { false };
|
||||
bool m_show_drop_to_bed { false };
|
||||
bool m_enable_drop_to_bed { false };
|
||||
enum class RotateType { None, Relative, Absolute
|
||||
};
|
||||
RotateType m_last_rotate_type{RotateType::None}; // 0:no input 1:relative 2:absolute
|
||||
|
||||
@@ -365,7 +365,7 @@ std::vector<NativeCommand> build_command_catalog()
|
||||
return object_op(wxGetApp().plater(), [](Plater* p) { return !p->is_selection_empty(); }, [](Plater* p) { p->center_selection(); });
|
||||
});
|
||||
add_with_icon("obj_drop", L("Drop to Bed"), L("Object"), "toolbar_flatten", [](const std::string&) {
|
||||
return object_op(wxGetApp().plater(), [](Plater* p) { return !p->is_selection_empty(); }, [](Plater* p) { p->drop_selection(); });
|
||||
return object_op(wxGetApp().plater(), [](Plater* p) { return p->get_selection().can_drop(); }, [](Plater* p) { p->drop_selection(); });
|
||||
});
|
||||
add("obj_fit_volume", L("Scale to Fit Print Volume"), L("Object"), [](const std::string&) {
|
||||
return object_op(
|
||||
|
||||
@@ -558,15 +558,37 @@ void Selection::center()
|
||||
return;
|
||||
}
|
||||
|
||||
double Selection::get_drop_min_z() const
|
||||
{
|
||||
if (!m_valid)
|
||||
return 0.;
|
||||
if (m_mode == Volume)
|
||||
return get_bounding_box().min.z();
|
||||
|
||||
double min_z = DBL_MAX;
|
||||
for (const auto& [obj_idx, inst_idxs] : m_cache.content) {
|
||||
if (obj_idx >= (int)m_model->objects.size())
|
||||
continue; // wipe tower
|
||||
for (int inst_idx : inst_idxs)
|
||||
min_z = std::min(min_z, m_model->objects[obj_idx]->get_instance_min_z(inst_idx));
|
||||
}
|
||||
return min_z == DBL_MAX ? 0. : min_z;
|
||||
}
|
||||
|
||||
bool Selection::can_drop() const
|
||||
{
|
||||
return std::abs(get_drop_min_z()) > -SINKING_Z_THRESHOLD;
|
||||
}
|
||||
|
||||
void Selection::drop()
|
||||
{
|
||||
if (std::abs(this->get_bounding_box().min.z()) < -SINKING_Z_THRESHOLD) {
|
||||
return; // shouldnt happen, but better check anyways, already checked in append_menu_item_drop()
|
||||
}
|
||||
const double min_z = get_drop_min_z();
|
||||
if (std::abs(min_z) < -SINKING_Z_THRESHOLD)
|
||||
return; // already checked in can_drop()
|
||||
|
||||
wxGetApp().plater()->take_snapshot(L("Move object"));
|
||||
|
||||
this->move_to_center(Vec3d(0, 0, -this->get_bounding_box().min.z()));
|
||||
this->move_to_center(Vec3d(0, 0, -min_z));
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume& volume = *(*m_volumes)[i];
|
||||
|
||||
@@ -248,6 +248,9 @@ public:
|
||||
void clone(int numbers = 1);
|
||||
void center();
|
||||
void drop();
|
||||
bool can_drop() const;
|
||||
// Lowest world Z that drop() moves to the bed; whole objects count model parts only, as auto drop does.
|
||||
double get_drop_min_z() const;
|
||||
void center_plate(const int plate_idx);
|
||||
void set_printable(bool printable);
|
||||
bool get_auto_drop() const;
|
||||
|
||||
Reference in New Issue
Block a user