PrusaSlicer-NonPlainar/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp

331 lines
12 KiB
C++

#ifndef slic3r_GLGizmoCut_hpp_
#define slic3r_GLGizmoCut_hpp_
#include "GLGizmoBase.hpp"
#include "slic3r/GUI/GLSelectionRectangle.hpp"
#include "slic3r/GUI/GLModel.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Model.hpp"
#include "imgui/imgui.h"
namespace Slic3r {
enum class CutConnectorType : int;
class ModelVolume;
struct CutConnectorAttributes;
namespace GUI {
class Selection;
enum class SLAGizmoEventType : unsigned char;
class GLGizmoCut3D : public GLGizmoBase
{
enum GrabberID {
X = 0,
Y,
Z,
CutPlane,
Count,
};
Transform3d m_rotation_m{ Transform3d::Identity() };
double m_snap_step{ 1.0 };
int m_connectors_group_id;
// archived values
Vec3d m_ar_plane_center { Vec3d::Zero() };
Transform3d m_start_dragging_m{ Transform3d::Identity() };
Vec3d m_plane_center{ Vec3d::Zero() };
// data to check position of the cut palne center on gizmo activation
Vec3d m_min_pos{ Vec3d::Zero() };
Vec3d m_max_pos{ Vec3d::Zero() };
Vec3d m_bb_center{ Vec3d::Zero() };
Vec3d m_center_offset{ Vec3d::Zero() };
BoundingBoxf3 m_bounding_box;
BoundingBoxf3 m_transformed_bounding_box;
// values from RotationGizmo
double m_radius{ 0.0 };
double m_grabber_radius{ 0.0 };
double m_grabber_connection_len{ 0.0 };
double m_snap_coarse_in_radius{ 0.0 };
double m_snap_coarse_out_radius{ 0.0 };
double m_snap_fine_in_radius{ 0.0 };
double m_snap_fine_out_radius{ 0.0 };
// dragging angel in hovered axes
double m_angle{ 0.0 };
TriangleMesh m_connector_mesh;
// workaround for using of the clipping plane normal
Vec3d m_clp_normal{ Vec3d::Ones() };
Vec3d m_line_beg{ Vec3d::Zero() };
Vec3d m_line_end{ Vec3d::Zero() };
Vec2d m_ldown_mouse_position{ Vec2d::Zero() };
GLModel m_grabber_connection;
GLModel m_cut_line;
PickingModel m_plane;
PickingModel m_sphere;
PickingModel m_cone;
std::map<CutConnectorAttributes, PickingModel> m_shapes;
std::vector<std::shared_ptr<SceneRaycasterItem>> m_raycasters;
GLModel m_circle;
GLModel m_scale;
GLModel m_snap_radii;
GLModel m_reference_radius;
GLModel m_angle_arc;
Vec3d m_old_center;
Vec3d m_cut_normal;
struct InvalidConnectorsStatistics
{
unsigned int outside_cut_contour;
unsigned int outside_bb;
bool is_overlap;
void invalidate() {
outside_cut_contour = 0;
outside_bb = 0;
is_overlap = false;
}
} m_info_stats;
bool m_keep_upper{ true };
bool m_keep_lower{ true };
bool m_keep_as_parts{ false };
bool m_place_on_cut_upper{ true };
bool m_place_on_cut_lower{ false };
bool m_rotate_upper{ false };
bool m_rotate_lower{ false };
bool m_hide_cut_plane{ false };
bool m_connectors_editing{ false };
bool m_cut_plane_as_circle{ false };
float m_connector_depth_ratio{ 3.f };
float m_connector_size{ 2.5f };
float m_connector_depth_ratio_tolerance{ 0.1f };
float m_connector_size_tolerance{ 0.f };
float m_label_width{ 0.f };
float m_control_width{ 200.f };
bool m_imperial_units{ false };
float m_contour_width{ 0.4f };
float m_cut_plane_radius_koef{ 1.5f };
bool m_is_contour_changed{ false };
float m_shortcut_label_width{ -1.f };
mutable std::vector<bool> m_selected; // which pins are currently selected
int m_selected_count{ 0 };
GLSelectionRectangle m_selection_rectangle;
bool m_has_invalid_connector{ false };
bool m_was_cut_plane_dragged { false };
bool m_was_contour_selected { false };
struct PartSelection {
PartSelection() = default;
PartSelection(ModelObject* mo, int instance_idx, const Vec3d& center, const Vec3d& normal);
void render(const Vec3d* normal = nullptr);
void toggle_selection(const Vec2d& mouse_pos);
void turn_over_selection();
struct Part {
GLModel glmodel;
MeshRaycaster raycaster;
bool selected;
bool upper;
};
ModelObject* model_object; // FIXME: Ownership !
int instance_idx;
std::vector<Part> parts;
bool valid = false;
};
PartSelection m_part_selection;
ModelObjectPtrs m_cut_part_ptrs;
bool m_show_shortcuts{ false };
std::vector<std::pair<wxString, wxString>> m_shortcuts;
enum class CutMode {
cutPlanar
, cutGrig
//,cutRadial
//,cutModular
};
enum class CutConnectorMode {
Auto
, Manual
};
// std::vector<std::string> m_modes;
size_t m_mode{ size_t(CutMode::cutPlanar) };
std::vector<std::string> m_connector_modes;
CutConnectorMode m_connector_mode{ CutConnectorMode::Manual };
std::vector<std::string> m_connector_types;
CutConnectorType m_connector_type;
std::vector<std::string> m_connector_styles;
size_t m_connector_style;
std::vector<std::string> m_connector_shapes;
size_t m_connector_shape_id;
std::vector<std::string> m_axis_names;
std::map<std::string, wxString> m_part_orientation_names;
std::map<std::string, std::string> m_labels_map;
public:
GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
std::string get_tooltip() const override;
bool unproject_on_cut_plane(const Vec2d& mouse_pos, Vec3d& pos, Vec3d& pos_world, bool respect_disabled_contour = true);
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
bool is_in_editing_mode() const override { return m_connectors_editing; }
bool is_selection_rectangle_dragging() const override { return m_selection_rectangle.is_dragging(); }
bool is_looking_forward() const;
/// <summary>
/// Drag of plane
/// </summary>
/// <param name="mouse_event">Keep information about mouse click</param>
/// <returns>Return True when use the information otherwise False.</returns>
bool on_mouse(const wxMouseEvent &mouse_event) override;
void shift_cut(double delta);
void rotate_vec3d_around_plane_center(Vec3d&vec);
void put_connectors_on_cut_plane(const Vec3d& cp_normal, double cp_offset);
void update_clipper();
void invalidate_cut_plane();
BoundingBoxf3 bounding_box() const;
BoundingBoxf3 transformed_bounding_box(const Vec3d& plane_center, const Transform3d& rotation_m = Transform3d::Identity()) const;
protected:
bool on_init() override;
void on_load(cereal::BinaryInputArchive&ar) override;
void on_save(cereal::BinaryOutputArchive&ar) const override;
std::string on_get_name() const override;
void on_set_state() override;
CommonGizmosDataID on_get_requirements() const override;
void on_set_hover_id() override;
bool on_is_activable() const override;
bool on_is_selectable() const override;
Vec3d mouse_position_in_local_plane(GrabberID axis, const Linef3&mouse_ray) const;
void dragging_grabber_z(const GLGizmoBase::UpdateData &data);
void dragging_grabber_xy(const GLGizmoBase::UpdateData &data);
void dragging_connector(const GLGizmoBase::UpdateData &data);
void on_dragging(const UpdateData&data) override;
void on_start_dragging() override;
void on_stop_dragging() override;
void on_render() override;
void render_debug_input_window(float x);
void adjust_window_position(float x, float y, float bottom_limit);
void unselect_all_connectors();
void select_all_connectors();
void render_shortcuts();
void apply_selected_connectors(std::function<void(size_t idx)> apply_fn);
void render_connectors_input_window(CutConnectors &connectors);
void render_build_size();
void reset_cut_plane();
void set_connectors_editing(bool connectors_editing);
void flip_cut_plane();
void process_contours();
void reset_cut_by_contours();
void render_flip_plane_button(bool disable_pred = false);
void add_vertical_scaled_interval(float interval);
void add_horizontal_scaled_interval(float interval);
void add_horizontal_shift(float shift);
void render_color_marker(float size, const ImU32& color);
void render_cut_plane_input_window(CutConnectors &connectors);
void init_input_window_data(CutConnectors &connectors);
void render_input_window_warning() const;
bool add_connector(CutConnectors&connectors, const Vec2d&mouse_position);
bool delete_selected_connectors(CutConnectors&connectors);
void select_connector(int idx, bool select);
bool is_selection_changed(bool alt_down, bool shift_down);
void process_selection_rectangle(CutConnectors &connectors);
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
void update_raycasters_for_picking();
void set_volumes_picking_state(bool state);
void update_raycasters_for_picking_transform();
void on_render_input_window(float x, float y, float bottom_limit) override;
bool wants_enter_leave_snapshots() const override { return true; }
std::string get_gizmo_entering_text() const override { return _u8L("Entering Cut gizmo"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Cut gizmo"); }
std::string get_action_snapshot_name() const override { return _u8L("Cut gizmo editing"); }
void data_changed(bool is_serializing) override;
Transform3d get_cut_matrix(const Selection& selection);
private:
void set_center(const Vec3d& center, bool update_tbb = false);
bool render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
bool render_double_input(const std::string& label, double& value_in);
bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in);
void render_move_center_input(int axis);
void render_connect_mode_radio_button(CutConnectorMode mode);
bool render_reset_button(const std::string& label_id, const std::string& tooltip) const;
bool render_connect_type_radio_button(CutConnectorType type);
bool is_outside_of_cut_contour(size_t idx, const CutConnectors& connectors, const Vec3d cur_pos);
bool is_conflict_for_connector(size_t idx, const CutConnectors& connectors, const Vec3d cur_pos);
void render_connectors();
bool can_perform_cut() const;
bool has_valid_contour() const;
void apply_connectors_in_model(ModelObject* mo, bool &create_dowels_as_separate_object);
bool cut_line_processing() const;
void discard_cut_line_processing();
void render_cut_plane();
void render_model(GLModel& model, const ColorRGBA& color, Transform3d view_model_matrix);
void render_line(GLModel& line_model, const ColorRGBA& color, Transform3d view_model_matrix, float width);
void render_rotation_snapping(GrabberID axis, const ColorRGBA& color);
void render_grabber_connection(const ColorRGBA& color, Transform3d view_matrix);
void render_cut_plane_grabbers();
void render_cut_line();
void perform_cut(const Selection&selection);
void set_center_pos(const Vec3d&center_pos, bool update_tbb = false);
void update_bb();
void init_picking_models();
void init_rendering_items();
void render_clipper_cut();
void clear_selection();
void reset_connectors();
void init_connector_shapes();
void update_connector_shape();
void validate_connector_settings();
bool process_cut_line(SLAGizmoEventType action, const Vec2d& mouse_position);
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GLGizmoCut_hpp_