2022-07-15 15:37:19 +00:00
# ifndef slic3r_GLGizmoAdvancedCut_hpp_
# define slic3r_GLGizmoAdvancedCut_hpp_
# include "GLGizmoBase.hpp"
# include "GLGizmoRotate.hpp"
2023-03-14 02:42:42 +00:00
# include "libslic3r/Model.hpp"
2023-09-20 03:06:28 +00:00
# include "libslic3r/CutUtils.hpp"
# include "slic3r/GUI/MeshUtils.hpp"
2022-07-15 15:37:19 +00:00
namespace Slic3r {
2023-03-14 02:42:42 +00:00
enum class CutConnectorType : int ;
class ModelVolume ;
struct CutConnectorAttributes ;
2022-07-15 15:37:19 +00:00
namespace GUI {
2023-03-14 02:42:42 +00:00
enum class SLAGizmoEventType : unsigned char ;
2022-07-15 15:37:19 +00:00
2023-09-20 03:06:28 +00:00
namespace CommonGizmosDataObjects {
class ObjectClipper ;
}
class PartSelection
{
public :
PartSelection ( ) = default ;
PartSelection (
const ModelObject * mo , const Transform3d & cut_matrix , int instance_idx , const Vec3d & center , const Vec3d & normal , const CommonGizmosDataObjects : : ObjectClipper & oc ) ;
PartSelection ( const ModelObject * mo , int instance_idx_in ) ;
~ PartSelection ( )
{
m_model . clear_objects ( ) ;
for ( size_t i = 0 ; i < m_cut_parts . size ( ) ; i + + ) {
if ( m_cut_parts [ i ] . raycaster ) { delete m_cut_parts [ i ] . raycaster ; }
}
}
struct PartPara
{
GLModel glmodel ;
MeshRaycaster * raycaster ;
bool is_up_part ;
Transform3d trans ;
} ;
void part_render ( const Vec3d * normal ) ;
void toggle_selection ( const Vec2d & mouse_pos ) ;
void toggle_selection ( int id ) ;
void turn_over_selection ( ) ;
ModelObject * model_object ( ) { return m_model . objects . front ( ) ; }
bool valid ( ) const { return m_valid ; }
bool is_one_object ( ) const ;
const std : : vector < size_t > * get_ignored_contours_ptr ( ) const { return ( valid ( ) ? & m_ignored_contours : nullptr ) ; }
std : : vector < Cut : : Part > get_cut_parts ( ) ;
std : : vector < PartPara > & get_parts ( ) { return m_cut_parts ; }
private :
Model m_model ;
int m_instance_idx ;
std : : vector < PartPara > m_cut_parts ;
bool m_valid = false ;
std : : vector < std : : pair < std : : vector < size_t > , std : : vector < size_t > > > m_contour_to_parts ; // for each contour, there is a vector of parts above and a vector of parts below
std : : vector < size_t > m_ignored_contours ; // contour that should not be rendered (the parts on both sides will both be parts of the same object)
std : : vector < Vec3d > m_contour_points ; // Debugging
std : : vector < std : : vector < Vec3d > > m_debug_pts ; // Debugging
void add_object ( const ModelObject * object ) ;
} ;
2022-07-15 15:37:19 +00:00
class GLGizmoAdvancedCut : public GLGizmoRotate3D
{
struct Rotate_data {
double angle ;
Axis ax ;
Rotate_data ( double an , Axis a )
: angle ( an ) , ax ( a )
{
}
} ;
private :
static const double Offset ;
static const double Margin ;
static const std : : array < float , 4 > GrabberColor ;
static const std : : array < float , 4 > GrabberHoverColor ;
mutable double m_movement ;
mutable double m_height ; // height of cut plane to heatbed
mutable double m_height_delta ; // height of cut plane to heatbed
double m_start_movement ;
double m_start_height ;
Vec3d m_rotation ;
//Vec3d m_current_base_rotation;
std : : vector < Rotate_data > m_rotate_cmds ;
Vec3d m_buffered_rotation ;
double m_buffered_movement ;
double m_buffered_height ;
Vec3d m_drag_pos ;
bool m_keep_upper ;
bool m_keep_lower ;
2023-03-20 09:14:41 +00:00
bool m_cut_to_parts ;
2023-03-14 02:42:42 +00:00
bool m_place_on_cut_upper { true } ;
bool m_place_on_cut_lower { false } ;
bool m_rotate_upper { false } ;
bool m_rotate_lower { false } ;
2022-07-15 15:37:19 +00:00
bool m_do_segment ;
double m_segment_smoothing_alpha ;
int m_segment_number ;
std : : array < Vec3d , 4 > m_cut_plane_points ;
mutable Grabber m_move_grabber ;
unsigned int m_last_active_id ;
2023-03-14 02:42:42 +00:00
bool m_connectors_editing { false } ;
bool m_show_shortcuts { false } ;
std : : vector < std : : pair < wxString , wxString > > m_shortcuts ;
double m_label_width { 150.0 } ;
double m_control_width { 200.0 } ;
2023-03-24 09:57:27 +00:00
double m_editing_window_width ;
2023-03-14 02:42:42 +00:00
CutConnectorType m_connector_type ;
size_t m_connector_style ;
size_t m_connector_shape_id ;
float m_connector_depth_ratio { 3.f } ;
float m_connector_depth_ratio_tolerance { 0.1f } ;
float m_connector_size { 2.5f } ;
float m_connector_size_tolerance { 0.f } ;
2023-08-25 07:36:04 +00:00
// Input params for cut with snaps
float m_snap_space_proportion { 0.3f } ;
float m_snap_bulge_proportion { 0.15f } ;
2023-03-14 02:42:42 +00:00
TriangleMesh m_connector_mesh ;
bool m_has_invalid_connector { false } ;
// remember the connectors which is selected
mutable std : : vector < bool > m_selected ;
int m_selected_count { 0 } ;
Vec3d m_cut_plane_center { Vec3d : : Zero ( ) } ;
Vec3d m_cut_plane_normal { Vec3d : : UnitZ ( ) } ;
Vec3d m_cut_line_begin { Vec3d : : Zero ( ) } ;
Vec3d m_cut_line_end { Vec3d : : Zero ( ) } ;
Transform3d m_rotate_matrix { Transform3d : : Identity ( ) } ;
std : : map < CutConnectorAttributes , GLModel > m_shapes ;
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 ;
//GLSelectionRectangle m_selection_rectangle;
2022-07-15 15:37:19 +00:00
public :
GLGizmoAdvancedCut ( GLCanvas3D & parent , const std : : string & icon_filename , unsigned int sprite_id ) ;
2023-03-14 02:42:42 +00:00
bool gizmo_event ( SLAGizmoEventType action , const Vec2d & mouse_position , bool shift_down , bool alt_down , bool control_down ) ;
bool on_key ( wxKeyEvent & evt ) ;
2022-07-15 15:37:19 +00:00
double get_movement ( ) const { return m_movement ; }
void set_movement ( double movement ) const ;
void finish_rotation ( ) ;
std : : string get_tooltip ( ) const override ;
2023-03-14 02:42:42 +00:00
BoundingBoxf3 bounding_box ( ) const ;
//BoundingBoxf3 transformed_bounding_box(const Vec3d &plane_center, bool revert_move = false) const;
bool is_looking_forward ( ) const ;
bool unproject_on_cut_plane ( const Vec2d & mouse_pos , Vec3d & pos , Vec3d & pos_world ) ;
2023-09-18 11:41:32 +00:00
virtual bool apply_clipping_plane ( ) { return m_connectors_editing ; }
static void render_glmodel ( GLModel & model , const std : : array < float , 4 > & color , Transform3d view_model_matrix , bool for_picking = false ) ;
2022-07-15 15:37:19 +00:00
protected :
virtual bool on_init ( ) ;
2023-03-14 02:42:42 +00:00
virtual void on_load ( cereal : : BinaryInputArchive & ar ) override ;
virtual void on_save ( cereal : : BinaryOutputArchive & ar ) const override ;
2022-07-15 15:37:19 +00:00
virtual std : : string on_get_name ( ) const ;
virtual void on_set_state ( ) ;
virtual bool on_is_activable ( ) const ;
2023-03-14 02:42:42 +00:00
virtual CommonGizmosDataID on_get_requirements ( ) const override ;
virtual void on_start_dragging ( ) override ;
virtual void on_stop_dragging ( ) override ;
2022-07-15 15:37:19 +00:00
virtual void on_update ( const UpdateData & data ) ;
virtual void on_render ( ) ;
virtual void on_render_for_picking ( ) ;
virtual void on_render_input_window ( float x , float y , float bottom_limit ) ;
2023-03-14 02:42:42 +00:00
void show_tooltip_information ( float x , float y ) ;
2022-07-15 15:37:19 +00:00
virtual void on_enable_grabber ( unsigned int id )
{
if ( id < 3 )
m_gizmos [ id ] . enable_grabber ( 0 ) ;
else if ( id = = 3 )
this - > enable_grabber ( 0 ) ;
}
virtual void on_disable_grabber ( unsigned int id )
{
if ( id < 3 )
m_gizmos [ id ] . disable_grabber ( 0 ) ;
else if ( id = = 3 )
this - > disable_grabber ( 0 ) ;
}
virtual void on_set_hover_id ( )
{
for ( int i = 0 ; i < 3 ; + + i )
m_gizmos [ i ] . set_hover_id ( ( m_hover_id = = i ) ? 0 : - 1 ) ;
}
private :
void perform_cut ( const Selection & selection ) ;
2023-03-14 02:42:42 +00:00
bool can_perform_cut ( ) const ;
void apply_connectors_in_model ( ModelObject * mo , bool & create_dowels_as_separate_object ) ;
bool is_selection_changed ( bool alt_down , bool shift_down ) ;
void select_connector ( int idx , bool select ) ;
2022-07-15 15:37:19 +00:00
double calc_projection ( const Linef3 & mouse_ray ) const ;
Vec3d calc_plane_normal ( const std : : array < Vec3d , 4 > & plane_points ) const ;
Vec3d calc_plane_center ( const std : : array < Vec3d , 4 > & plane_points ) const ;
Vec3d get_plane_normal ( ) const ;
Vec3d get_plane_center ( ) const ;
void update_plane_points ( ) ;
std : : array < Vec3d , 4 > get_plane_points ( ) const ;
std : : array < Vec3d , 4 > get_plane_points_world_coord ( ) const ;
void reset_cut_plane ( ) ;
void reset_all ( ) ;
2023-03-14 02:42:42 +00:00
// update the connectors position so that the connectors are on the cut plane
void put_connectors_on_cut_plane ( const Vec3d & cp_normal , double cp_offset ) ;
void update_clipper ( ) ;
// on render
void render_cut_plane_and_grabbers ( ) ;
void render_connectors ( ) ;
void render_clipper_cut ( ) ;
void render_cut_line ( ) ;
void clear_selection ( ) ;
void init_connector_shapes ( ) ;
void set_connectors_editing ( bool connectors_editing ) ;
void reset_connectors ( ) ;
void update_connector_shape ( ) ;
void apply_selected_connectors ( std : : function < void ( size_t idx ) > apply_fn ) ;
void select_all_connectors ( ) ;
void unselect_all_connectors ( ) ;
void validate_connector_settings ( ) ;
bool add_connector ( CutConnectors & connectors , const Vec2d & mouse_position ) ;
bool delete_selected_connectors ( ) ;
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 check_conflict_for_all_connectors ( ) ;
// render input window
void render_cut_plane_input_window ( float x , float y , float bottom_limit ) ;
void init_connectors_input_window_data ( ) ;
void render_connectors_input_window ( float x , float y , float bottom_limit ) ;
void render_input_window_warning ( ) const ;
bool render_reset_button ( const std : : string & label_id , const std : : string & tooltip ) const ;
bool render_connect_type_radio_button ( CutConnectorType type ) ;
bool render_combo ( const std : : string & label , const std : : vector < std : : string > & lines , size_t & selection_idx ) ;
bool render_slider_double_input ( const std : : string & label , float & value_in , float & tolerance_in ) ;
2023-09-19 02:15:21 +00:00
enum DoubleShowType {
Normal , // origin data
PERCENTAGE ,
DEGREE ,
} ;
bool render_slider_double_input_by_format ( const std : : string & label , float & value_in , float value_min , float value_max , DoubleShowType show_type = DoubleShowType : : Normal ) ;
2023-03-14 02:42:42 +00:00
bool cut_line_processing ( ) const ;
void discard_cut_line_processing ( ) ;
bool process_cut_line ( SLAGizmoEventType action , const Vec2d & mouse_position ) ;
2022-07-15 15:37:19 +00:00
} ;
} // namespace GUI
} // namespace Slic3r
# endif // slic3r_GLGizmoAdvancedCut_hpp_