Cut: Extensions for Dialog of CutGizmo

This commit is contained in:
YuSanka 2022-01-27 17:23:10 +01:00
parent 6c397e291c
commit f7284a6569
2 changed files with 194 additions and 16 deletions

View File

@ -27,7 +27,22 @@ static const ColorRGBA GRABBER_COLOR = ColorRGBA::ORANGE();
GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id)
{} {
m_modes = { _u8L("Planar"), _u8L("Grid")
// , _u8L("Radial"), _u8L("Modular")
};
m_connector_types = { _u8L("Plug"), _u8L("Dowel") };
m_connector_styles = { _u8L("Prizm"), _u8L("Frustrum")
// , _u8L("Claw")
};
m_connector_shapes = { _u8L("Triangle"), _u8L("Square"), _u8L("Circle"), _u8L("Hexagon")
// , _u8L("D-shape")
};
}
std::string GLGizmoCut::get_tooltip() const std::string GLGizmoCut::get_tooltip() const
{ {
@ -220,6 +235,86 @@ void GLGizmoCut::on_render_for_picking()
render_grabbers_for_picking(m_parent.get_selection().get_bounding_box()); render_grabbers_for_picking(m_parent.get_selection().get_bounding_box());
} }
void GLGizmoCut::render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx)
{
ImGui::AlignTextToFramePadding();
m_imgui->text(label);
ImGui::SameLine(m_label_width);
ImGui::PushItemWidth(m_control_width);
size_t selection_out = selection_idx;
// It is necessary to use BeginGroup(). Otherwise, when using SameLine() is called, then other items will be drawn inside the combobox.
ImGui::BeginGroup();
ImVec2 combo_pos = ImGui::GetCursorScreenPos();
if (ImGui::BeginCombo(("##"+label).c_str(), "")) {
for (size_t line_idx = 0; line_idx < lines.size(); ++line_idx) {
ImGui::PushID(int(line_idx));
ImVec2 start_position = ImGui::GetCursorScreenPos();
if (ImGui::Selectable("", line_idx == selection_idx))
selection_out = line_idx;
ImGui::SameLine();
ImGui::Text("%s", lines[line_idx].c_str());
ImGui::PopID();
}
ImGui::EndCombo();
}
ImVec2 backup_pos = ImGui::GetCursorScreenPos();
ImGuiStyle& style = ImGui::GetStyle();
ImGui::SetCursorScreenPos(ImVec2(combo_pos.x + style.FramePadding.x, combo_pos.y + style.FramePadding.y));
ImGui::Text("%s", lines[selection_out].c_str());
ImGui::SetCursorScreenPos(backup_pos);
ImGui::EndGroup();
selection_idx = selection_out;
}
void GLGizmoCut::render_double_input(const std::string& label, double& value_in)
{
ImGui::AlignTextToFramePadding();
m_imgui->text(label);
ImGui::SameLine(m_label_width);
ImGui::PushItemWidth(m_control_width);
double value = value_in;
if (m_imperial_units)
value *= ObjectManipulation::mm_to_in;
ImGui::InputDouble(("##" + label).c_str(), &value, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_CharsDecimal);
ImGui::SameLine();
m_imgui->text(m_imperial_units ? _L("in") : _L("mm"));
value_in = value * (m_imperial_units ? ObjectManipulation::in_to_mm : 1.0);
}
void GLGizmoCut::render_rotation_input(const std::string& label, double& value_in)
{
m_imgui->text(label);
ImGui::SameLine();
double value = value_in;
if (value > 360)
value -= 360;
ImGui::PushItemWidth(0.3*m_control_width);
ImGui::InputDouble(("##" + label).c_str(), &value, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_CharsDecimal);
value_in = value;
}
void GLGizmoCut::render_radio_button(ConnectorType type)
{
ImGui::SameLine(type == ConnectorType::Plug ? m_label_width : 2*m_label_width);
ImGui::PushItemWidth(m_control_width);
if (m_imgui->radio_button(m_connector_types[int(type)], m_connector_type == type))
m_connector_type = type;
}
void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit) void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit)
{ {
static float last_y = 0.0f; static float last_y = 0.0f;
@ -227,7 +322,9 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit)
m_imgui->begin(_L("Cut"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); m_imgui->begin(_L("Cut"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
const bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; m_imperial_units = wxGetApp().app_config->get("use_inches") == "1";
m_label_width = m_imgui->get_style_scaling() * 100.0f;
m_control_width = m_imgui->get_style_scaling() * 150.0f;
// adjust window position to avoid overlap the view toolbar // adjust window position to avoid overlap the view toolbar
const float win_h = ImGui::GetWindowHeight(); const float win_h = ImGui::GetWindowHeight();
@ -242,26 +339,52 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit)
last_y = y; last_y = y;
} }
ImGui::AlignTextToFramePadding(); render_combo(_u8L("Mode"), m_modes, m_mode);
m_imgui->text("Z");
ImGui::SameLine();
ImGui::PushItemWidth(m_imgui->get_style_scaling() * 150.0f);
double cut_z = m_cut_z; if (m_mode == CutMode::cutPlanar) {
if (imperial_units) ImGui::Separator();
cut_z *= ObjectManipulation::mm_to_in;
ImGui::InputDouble("", &cut_z, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_CharsDecimal);
ImGui::SameLine(); render_double_input("Z", m_cut_z);
m_imgui->text(imperial_units ? _L("in") : _L("mm"));
m_cut_z = cut_z * (imperial_units ? ObjectManipulation::in_to_mm : 1.0); ImGui::AlignTextToFramePadding();
m_imgui->text(_L("Rotation"));
ImGui::SameLine(m_label_width);
render_rotation_input("X:", m_rotation_x);
ImGui::SameLine();
render_rotation_input("Y:", m_rotation_y);
ImGui::SameLine();
render_rotation_input("Z:", m_rotation_z);
ImGui::SameLine();
m_imgui->text(_L("°"));
ImGui::AlignTextToFramePadding();
m_imgui->text(_L("After cut"));
ImGui::SameLine(m_label_width);
m_imgui->checkbox(_L("Keep upper part"), m_keep_upper);
m_imgui->text("");
ImGui::SameLine(m_label_width);
m_imgui->checkbox(_L("Keep lower part"), m_keep_lower);
m_imgui->text("");
ImGui::SameLine(m_label_width);
m_imgui->disabled_begin(!m_keep_lower);
m_imgui->checkbox(_L("Rotate lower part upwards"), m_rotate_lower);
m_imgui->disabled_end();
}
// Connectors section
ImGui::Separator(); ImGui::Separator();
m_imgui->checkbox(_L("Keep upper part"), m_keep_upper); m_imgui->text(_L("Connectors"));
m_imgui->checkbox(_L("Keep lower part"), m_keep_lower); render_radio_button(ConnectorType::Plug);
m_imgui->checkbox(_L("Rotate lower part upwards"), m_rotate_lower); render_radio_button(ConnectorType::Dowel);
render_combo(_u8L("Style"), m_connector_styles, m_connector_style);
render_combo(_u8L("Shape"), m_connector_shapes, m_connector_shape);
render_double_input(_u8L("Depth ratio"), m_connector_depth_ratio);
render_double_input(_u8L("Size"), m_connector_size);
ImGui::Separator(); ImGui::Separator();

View File

@ -15,6 +15,9 @@ class GLGizmoCut : public GLGizmoBase
static const double Margin; static const double Margin;
double m_cut_z{ 0.0 }; double m_cut_z{ 0.0 };
double m_rotation_x{ 0.0 };
double m_rotation_y{ 0.0 };
double m_rotation_z{ 0.0 };
double m_max_z{ 0.0 }; double m_max_z{ 0.0 };
double m_start_z{ 0.0 }; double m_start_z{ 0.0 };
Vec3d m_drag_pos; Vec3d m_drag_pos;
@ -27,6 +30,53 @@ class GLGizmoCut : public GLGizmoBase
GLModel m_grabber_connection; GLModel m_grabber_connection;
float m_old_z{ 0.0f }; float m_old_z{ 0.0f };
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL #endif // ENABLE_GLBEGIN_GLEND_REMOVAL
double m_connector_depth_ratio{ 1.5 };
double m_connector_size{ 5.0 };
float m_label_width{ 150.0 };
float m_control_width{ 200.0 };
bool m_imperial_units{ false };
public:
enum CutMode {
cutPlanar = 0
,cutGrig
//,cutRadial
//,cutModular
};
enum ConnectorType {
Plug = 0
,Dowel
};
enum ConnectorStyle {
Prizm = 0
,Frustrum
//,Claw
};
enum ConnectorShape {
Triangle = 0
,Square
,Circle
,Hexagon
// ,D-shape
};
private:
std::vector<std::string> m_modes;
size_t m_mode{ size_t(cutPlanar) };
std::vector<std::string> m_connector_types;
ConnectorType m_connector_type{ Plug };
std::vector<std::string> m_connector_styles;
size_t m_connector_style{ size_t(Prizm) };
std::vector<std::string> m_connector_shapes;
size_t m_connector_shape{ size_t(Hexagon) };
struct CutContours struct CutContours
{ {
@ -63,6 +113,11 @@ protected:
virtual void on_render_for_picking() override; virtual void on_render_for_picking() override;
virtual void on_render_input_window(float x, float y, float bottom_limit) override; virtual void on_render_input_window(float x, float y, float bottom_limit) override;
void render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
void render_double_input(const std::string& label, double& value_in);
void render_rotation_input(const std::string& label, double& value_in);
void render_radio_button(ConnectorType type);
private: private:
void perform_cut(const Selection& selection); void perform_cut(const Selection& selection);
double calc_projection(const Linef3& mouse_ray) const; double calc_projection(const Linef3& mouse_ray) const;