2022-07-15 15:37:19 +00:00
# include "GLGizmoMmuSegmentation.hpp"
# include "slic3r/GUI/GLCanvas3D.hpp"
# include "slic3r/GUI/GUI_App.hpp"
# include "slic3r/GUI/ImGuiWrapper.hpp"
# include "slic3r/GUI/Camera.hpp"
# include "slic3r/GUI/Plater.hpp"
# include "slic3r/GUI/BitmapCache.hpp"
# include "slic3r/GUI/format.hpp"
# include "slic3r/GUI/GUI_ObjectList.hpp"
# include "slic3r/GUI/NotificationManager.hpp"
# include "libslic3r/PresetBundle.hpp"
# include "libslic3r/Model.hpp"
# include "slic3r/Utils/UndoRedo.hpp"
# include <GL/glew.h>
namespace Slic3r : : GUI {
static inline void show_notification_extruders_limit_exceeded ( )
{
wxGetApp ( )
. plater ( )
- > get_notification_manager ( )
- > push_notification ( NotificationType : : MmSegmentationExceededExtrudersLimit , NotificationManager : : NotificationLevel : : PrintInfoNotificationLevel ,
GUI : : format ( _L ( " Filament count exceeds the maximum number that painting tool supports. only the "
" first %1% filaments will be available in painting tool. " ) , GLGizmoMmuSegmentation : : EXTRUDERS_LIMIT ) ) ;
}
void GLGizmoMmuSegmentation : : on_opening ( )
{
if ( wxGetApp ( ) . filaments_cnt ( ) > int ( GLGizmoMmuSegmentation : : EXTRUDERS_LIMIT ) )
show_notification_extruders_limit_exceeded ( ) ;
}
void GLGizmoMmuSegmentation : : on_shutdown ( )
{
m_parent . use_slope ( false ) ;
m_parent . toggle_model_objects_visibility ( true ) ;
}
std : : string GLGizmoMmuSegmentation : : on_get_name ( ) const
{
return _u8L ( " Color Painting " ) ;
}
bool GLGizmoMmuSegmentation : : on_is_selectable ( ) const
{
return ( wxGetApp ( ) . preset_bundle - > printers . get_edited_preset ( ) . printer_technology ( ) = = ptFFF
& & /*wxGetApp().get_mode() != comSimple && */ wxGetApp ( ) . filaments_cnt ( ) > 1 ) ;
}
bool GLGizmoMmuSegmentation : : on_is_activable ( ) const
{
return GLGizmoPainterBase : : on_is_activable ( ) & & wxGetApp ( ) . filaments_cnt ( ) > 1 ;
}
//BBS: use the global one in 3DScene.cpp
/*static std::vector<std::array<float, 4>> get_extruders_colors()
{
unsigned char rgb_color [ 3 ] = { } ;
std : : vector < std : : string > colors = Slic3r : : GUI : : wxGetApp ( ) . plater ( ) - > get_extruder_colors_from_plater_config ( ) ;
std : : vector < std : : array < float , 4 > > colors_out ( colors . size ( ) ) ;
for ( const std : : string & color : colors ) {
Slic3r : : GUI : : BitmapCache : : parse_color ( color , rgb_color ) ;
size_t color_idx = & color - & colors . front ( ) ;
colors_out [ color_idx ] = { float ( rgb_color [ 0 ] ) / 255.f , float ( rgb_color [ 1 ] ) / 255.f , float ( rgb_color [ 2 ] ) / 255.f , 1.f } ;
}
return colors_out ;
} */
static std : : vector < int > get_extruder_id_for_volumes ( const ModelObject & model_object )
{
std : : vector < int > extruders_idx ;
extruders_idx . reserve ( model_object . volumes . size ( ) ) ;
for ( const ModelVolume * model_volume : model_object . volumes ) {
if ( ! model_volume - > is_model_part ( ) )
continue ;
extruders_idx . emplace_back ( model_volume - > extruder_id ( ) ) ;
}
return extruders_idx ;
}
void GLGizmoMmuSegmentation : : init_extruders_data ( )
{
m_extruders_colors = get_extruders_colors ( ) ;
m_selected_extruder_idx = 0 ;
}
bool GLGizmoMmuSegmentation : : on_init ( )
{
// BBS
2022-07-28 02:15:33 +00:00
m_shortcut_key = WXK_CONTROL_N ;
2022-07-15 15:37:19 +00:00
m_desc [ " clipping_of_view " ] = _L ( " Section view " ) + " : " ;
m_desc [ " cursor_size " ] = _L ( " Pen size " ) + " : " ;
m_desc [ " cursor_type " ] = _L ( " Pen shape " ) ;
// BBS
m_desc [ " paint_caption " ] = _L ( " Left mouse button " ) + " : " ;
m_desc [ " paint " ] = _L ( " Paint " ) ;
m_desc [ " erase_caption " ] = _L ( " Right mouse button " ) + " : " ;
m_desc [ " erase " ] = _L ( " Erase " ) ;
m_desc [ " shortcut_key_caption " ] = _L ( " Key 1~9 " ) + " : " ;
m_desc [ " shortcut_key " ] = _L ( " Choose filament " ) ;
m_desc [ " edge_detection " ] = _L ( " Edge detection " ) ;
2022-07-23 08:46:17 +00:00
m_desc [ " gap_area " ] = _L ( " Gap area " ) ;
m_desc [ " perform " ] = _L ( " Perform " ) ;
2022-07-15 15:37:19 +00:00
2022-07-23 08:46:17 +00:00
m_desc [ " remove_all " ] = _L ( " Erase all painting " ) ;
2022-07-15 15:37:19 +00:00
m_desc [ " circle " ] = _L ( " Circle " ) ;
m_desc [ " sphere " ] = _L ( " Sphere " ) ;
m_desc [ " pointer " ] = _L ( " Triangles " ) ;
m_desc [ " filaments " ] = _L ( " Filaments " ) ;
m_desc [ " tool_type " ] = _L ( " Tool type " ) ;
m_desc [ " tool_brush " ] = _L ( " Brush " ) ;
m_desc [ " tool_smart_fill " ] = _L ( " Smart fill " ) ;
m_desc [ " tool_bucket_fill " ] = _L ( " Bucket fill " ) ;
m_desc [ " smart_fill_angle " ] = _L ( " Smart fill angle " ) ;
m_desc [ " brush_size " ] = _L ( " Set pen size " ) ;
m_desc [ " brush_size_caption " ] = _L ( " Ctrl + Mouse wheel " ) + " : " ;
// BBS
m_desc [ " height_range " ] = _L ( " Height range " ) ;
init_extruders_data ( ) ;
return true ;
}
GLGizmoMmuSegmentation : : GLGizmoMmuSegmentation ( GLCanvas3D & parent , const std : : string & icon_filename , unsigned int sprite_id )
: GLGizmoPainterBase ( parent , icon_filename , sprite_id ) , m_current_tool ( ImGui : : CircleButtonIcon )
{
}
void GLGizmoMmuSegmentation : : render_painter_gizmo ( ) const
{
const Selection & selection = m_parent . get_selection ( ) ;
glsafe ( : : glEnable ( GL_BLEND ) ) ;
glsafe ( : : glEnable ( GL_DEPTH_TEST ) ) ;
render_triangles ( selection ) ;
m_c - > object_clipper ( ) - > render_cut ( ) ;
m_c - > instances_hider ( ) - > render_cut ( ) ;
render_cursor ( ) ;
glsafe ( : : glDisable ( GL_BLEND ) ) ;
}
void GLGizmoMmuSegmentation : : set_painter_gizmo_data ( const Selection & selection )
{
GLGizmoPainterBase : : set_painter_gizmo_data ( selection ) ;
if ( m_state ! = On | | wxGetApp ( ) . preset_bundle - > printers . get_edited_preset ( ) . printer_technology ( ) ! = ptFFF | | wxGetApp ( ) . filaments_cnt ( ) < = 1 )
return ;
ModelObject * model_object = m_c - > selection_info ( ) - > model_object ( ) ;
int prev_extruders_count = int ( m_extruders_colors . size ( ) ) ;
if ( prev_extruders_count ! = wxGetApp ( ) . filaments_cnt ( ) ) {
if ( wxGetApp ( ) . filaments_cnt ( ) > int ( GLGizmoMmuSegmentation : : EXTRUDERS_LIMIT ) )
show_notification_extruders_limit_exceeded ( ) ;
this - > init_extruders_data ( ) ;
// Reinitialize triangle selectors because of change of extruder count need also change the size of GLIndexedVertexArray
if ( prev_extruders_count ! = wxGetApp ( ) . filaments_cnt ( ) )
this - > init_model_triangle_selectors ( ) ;
}
else if ( get_extruders_colors ( ) ! = m_extruders_colors ) {
this - > init_extruders_data ( ) ;
this - > update_triangle_selectors_colors ( ) ;
}
else if ( model_object ! = nullptr & & get_extruder_id_for_volumes ( * model_object ) ! = m_volumes_extruder_idxs ) {
this - > init_model_triangle_selectors ( ) ;
}
}
void GLGizmoMmuSegmentation : : render_triangles ( const Selection & selection ) const
{
ClippingPlaneDataWrapper clp_data = this - > get_clipping_plane_data ( ) ;
auto * shader = wxGetApp ( ) . get_shader ( " mm_gouraud " ) ;
if ( ! shader )
return ;
shader - > start_using ( ) ;
shader - > set_uniform ( " clipping_plane " , clp_data . clp_dataf ) ;
shader - > set_uniform ( " z_range " , clp_data . z_range ) ;
shader - > set_uniform ( " slope.actived " , m_parent . is_using_slope ( ) ) ;
ScopeGuard guard ( [ shader ] ( ) { if ( shader ) shader - > stop_using ( ) ; } ) ;
//BBS: to improve the random white pixel issue
glsafe ( : : glDisable ( GL_CULL_FACE ) ) ;
const ModelObject * mo = m_c - > selection_info ( ) - > model_object ( ) ;
int mesh_id = - 1 ;
for ( const ModelVolume * mv : mo - > volumes ) {
if ( ! mv - > is_model_part ( ) )
continue ;
+ + mesh_id ;
const Transform3d trafo_matrix = mo - > instances [ selection . get_instance_idx ( ) ] - > get_transformation ( ) . get_matrix ( ) * mv - > get_matrix ( ) ;
bool is_left_handed = trafo_matrix . matrix ( ) . determinant ( ) < 0. ;
if ( is_left_handed )
glsafe ( : : glFrontFace ( GL_CW ) ) ;
glsafe ( : : glPushMatrix ( ) ) ;
glsafe ( : : glMultMatrixd ( trafo_matrix . data ( ) ) ) ;
shader - > set_uniform ( " volume_world_matrix " , trafo_matrix ) ;
shader - > set_uniform ( " volume_mirrored " , is_left_handed ) ;
m_triangle_selectors [ mesh_id ] - > render ( m_imgui ) ;
glsafe ( : : glPopMatrix ( ) ) ;
if ( is_left_handed )
glsafe ( : : glFrontFace ( GL_CCW ) ) ;
}
}
// BBS
bool GLGizmoMmuSegmentation : : on_number_key_down ( int number )
{
int extruder_idx = number - 1 ;
if ( extruder_idx < m_extruders_colors . size ( ) )
m_selected_extruder_idx = extruder_idx ;
return true ;
}
static void render_extruders_combo ( const std : : string & label ,
const std : : vector < std : : string > & extruders ,
const std : : vector < std : : array < float , 4 > > & extruders_colors ,
size_t & selection_idx )
{
assert ( ! extruders_colors . empty ( ) ) ;
assert ( extruders_colors . size ( ) = = extruders_colors . size ( ) ) ;
auto convert_to_imu32 = [ ] ( const std : : array < float , 4 > & color ) - > ImU32 {
return IM_COL32 ( uint8_t ( color [ 0 ] * 255.f ) , uint8_t ( color [ 1 ] * 255.f ) , uint8_t ( color [ 2 ] * 255.f ) , uint8_t ( color [ 3 ] * 255.f ) ) ;
} ;
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 extruder_idx = 0 ; extruder_idx < std : : min ( extruders . size ( ) , GLGizmoMmuSegmentation : : EXTRUDERS_LIMIT ) ; + + extruder_idx ) {
ImGui : : PushID ( int ( extruder_idx ) ) ;
ImVec2 start_position = ImGui : : GetCursorScreenPos ( ) ;
if ( ImGui : : Selectable ( " " , extruder_idx = = selection_idx ) )
selection_out = extruder_idx ;
ImGui : : SameLine ( ) ;
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
float height = ImGui : : GetTextLineHeight ( ) ;
ImGui : : GetWindowDrawList ( ) - > AddRectFilled ( start_position , ImVec2 ( start_position . x + height + height / 2 , start_position . y + height ) , convert_to_imu32 ( extruders_colors [ extruder_idx ] ) ) ;
ImGui : : GetWindowDrawList ( ) - > AddRect ( start_position , ImVec2 ( start_position . x + height + height / 2 , start_position . y + height ) , IM_COL32_BLACK ) ;
ImGui : : SetCursorScreenPos ( ImVec2 ( start_position . x + height + height / 2 + style . FramePadding . x , start_position . y ) ) ;
ImGui : : Text ( " %s " , extruders [ extruder_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 ) ) ;
ImVec2 p = ImGui : : GetCursorScreenPos ( ) ;
float height = ImGui : : GetTextLineHeight ( ) ;
ImGui : : GetWindowDrawList ( ) - > AddRectFilled ( p , ImVec2 ( p . x + height + height / 2 , p . y + height ) , convert_to_imu32 ( extruders_colors [ selection_idx ] ) ) ;
ImGui : : GetWindowDrawList ( ) - > AddRect ( p , ImVec2 ( p . x + height + height / 2 , p . y + height ) , IM_COL32_BLACK ) ;
ImGui : : SetCursorScreenPos ( ImVec2 ( p . x + height + height / 2 + style . FramePadding . x , p . y ) ) ;
ImGui : : Text ( " %s " , extruders [ selection_out ] . c_str ( ) ) ;
ImGui : : SetCursorScreenPos ( backup_pos ) ;
ImGui : : EndGroup ( ) ;
selection_idx = selection_out ;
}
static std : : string into_u8 ( const wxString & str )
{
auto buffer_utf8 = str . utf8_str ( ) ;
return std : : string ( buffer_utf8 . data ( ) ) ;
}
void GLGizmoMmuSegmentation : : show_tooltip_information ( float caption_max , float x , float y )
{
ImTextureID normal_id = m_parent . get_gizmos_manager ( ) . get_icon_texture_id ( GLGizmosManager : : MENU_ICON_NAME : : IC_TOOLBAR_TOOLTIP ) ;
ImTextureID hover_id = m_parent . get_gizmos_manager ( ) . get_icon_texture_id ( GLGizmosManager : : MENU_ICON_NAME : : IC_TOOLBAR_TOOLTIP_HOVER ) ;
float font_size = ImGui : : GetFontSize ( ) ;
ImVec2 button_size = ImVec2 ( font_size * 1.8 , font_size * 1.3 ) ;
ImGui : : PushStyleVar ( ImGuiStyleVar_FrameBorderSize , 0.0f ) ;
ImGui : : ImageButton3 ( normal_id , hover_id , button_size ) ;
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : BeginTooltip2 ( ImVec2 ( x , y ) ) ;
auto draw_text_with_caption = [ this , & caption_max ] ( const wxString & caption , const wxString & text ) {
m_imgui - > text_colored ( ImGuiWrapper : : COL_ACTIVE , caption ) ;
ImGui : : SameLine ( caption_max ) ;
m_imgui - > text_colored ( ImGuiWrapper : : COL_WINDOW_BG , text ) ;
} ;
for ( const auto & t : std : : array < std : : string , 3 > { " paint " , " erase " , " brush_size " } ) draw_text_with_caption ( m_desc . at ( t + " _caption " ) , m_desc . at ( t ) ) ;
ImGui : : EndTooltip ( ) ;
}
ImGui : : PopStyleVar ( 1 ) ;
}
void GLGizmoMmuSegmentation : : on_render_input_window ( float x , float y , float bottom_limit )
{
if ( ! m_c - > selection_info ( ) - > model_object ( ) ) return ;
const float approx_height = m_imgui - > scaled ( 22.0f ) ;
y = std : : min ( y , bottom_limit - approx_height ) ;
GizmoImguiSetNextWIndowPos ( x , y , ImGuiCond_Always ) ;
wchar_t old_tool = m_current_tool ;
// BBS
ImGuiWrapper : : push_toolbar_style ( ) ;
ImGui : : PushStyleVar ( ImGuiStyleVar_WindowPadding , ImVec2 ( 8.0f , 16.0f ) ) ;
GizmoImguiBegin ( get_name ( ) , ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar ) ;
// First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that:
2022-07-22 09:46:10 +00:00
const float clipping_slider_left = m_imgui - > calc_text_size ( m_desc . at ( " clipping_of_view " ) ) . x + m_imgui - > scaled ( 1.f ) ;
2022-07-15 15:37:19 +00:00
const float cursor_slider_left = m_imgui - > calc_text_size ( m_desc . at ( " cursor_size " ) ) . x + m_imgui - > scaled ( 1.f ) ;
const float smart_fill_slider_left = m_imgui - > calc_text_size ( m_desc . at ( " smart_fill_angle " ) ) . x + m_imgui - > scaled ( 1.5f ) ;
const float edge_detect_slider_left = m_imgui - > calc_text_size ( m_desc . at ( " edge_detection " ) ) . x + m_imgui - > scaled ( 1.f ) ;
2022-07-23 08:46:17 +00:00
const float gap_area_slider_left = m_imgui - > calc_text_size ( m_desc . at ( " gap_area " ) ) . x + m_imgui - > scaled ( 1.5f ) ;
2022-07-22 09:46:10 +00:00
const float height_range_slider_left = m_imgui - > calc_text_size ( m_desc . at ( " height_range " ) ) . x + m_imgui - > scaled ( 1.5f ) ;
2022-07-15 15:37:19 +00:00
const float remove_btn_width = m_imgui - > calc_text_size ( m_desc . at ( " remove_all " ) ) . x + m_imgui - > scaled ( 1.f ) ;
2022-07-23 08:46:17 +00:00
const float filter_btn_width = m_imgui - > calc_text_size ( m_desc . at ( " perform " ) ) . x + m_imgui - > scaled ( 1.f ) ;
2022-07-15 15:37:19 +00:00
const float buttons_width = remove_btn_width + filter_btn_width + m_imgui - > scaled ( 1.f ) ;
const float minimal_slider_width = m_imgui - > scaled ( 4.f ) ;
const float color_button_width = m_imgui - > calc_text_size ( " " ) . x + m_imgui - > scaled ( 1.75f ) ;
float caption_max = 0.f ;
float total_text_max = 0.f ;
for ( const auto & t : std : : array < std : : string , 3 > { " paint " , " erase " , " brush_size " } ) {
caption_max = std : : max ( caption_max , m_imgui - > calc_text_size ( m_desc [ t + " _caption " ] ) . x ) ;
total_text_max = std : : max ( total_text_max , m_imgui - > calc_text_size ( m_desc [ t ] ) . x ) ;
}
total_text_max + = caption_max + m_imgui - > scaled ( 1.f ) ;
caption_max + = m_imgui - > scaled ( 1.f ) ;
2022-07-22 09:46:10 +00:00
const float circle_max_width = std : : max ( clipping_slider_left , cursor_slider_left ) ;
const float height_max_width = std : : max ( clipping_slider_left , height_range_slider_left ) ;
2022-07-15 15:37:19 +00:00
const float sliders_left_width = std : : max ( smart_fill_slider_left ,
2022-07-23 08:46:17 +00:00
std : : max ( cursor_slider_left , std : : max ( edge_detect_slider_left , std : : max ( gap_area_slider_left , std : : max ( height_range_slider_left ,
2022-07-15 15:37:19 +00:00
clipping_slider_left ) ) ) ) ) ;
const float slider_icon_width = m_imgui - > get_slider_icon_size ( ) . x ;
float window_width = minimal_slider_width + sliders_left_width + slider_icon_width ;
const int max_filament_items_per_line = 8 ;
const float empty_button_width = m_imgui - > calc_button_size ( " " ) . x ;
const float filament_item_width = empty_button_width + m_imgui - > scaled ( 1.5f ) ;
window_width = std : : max ( window_width , total_text_max ) ;
window_width = std : : max ( window_width , buttons_width ) ;
window_width = std : : max ( window_width , max_filament_items_per_line * filament_item_width + + m_imgui - > scaled ( 0.5f ) ) ;
const float max_tooltip_width = ImGui : : GetFontSize ( ) * 20.0f ;
float slider_width_times = 1.5 ;
ImDrawList * draw_list = ImGui : : GetWindowDrawList ( ) ;
ImVec2 pos = ImGui : : GetCursorScreenPos ( ) ;
static float color_button_high = 25.0 ;
draw_list - > AddRectFilled ( { pos . x - 10.0f , pos . y - 7.0f } , { pos . x + window_width + ImGui : : GetFrameHeight ( ) , pos . y + color_button_high } , ImGui : : GetColorU32 ( ImGuiCol_FrameBgActive , 1.0f ) , 5.0f ) ;
float color_button = ImGui : : GetCursorPos ( ) . y ;
m_imgui - > text ( m_desc . at ( " filaments " ) ) ;
float start_pos_x = ImGui : : GetCursorPos ( ) . x ;
const ImVec2 max_label_size = ImGui : : CalcTextSize ( " 99 " , NULL , true ) ;
const float item_spacing = m_imgui - > scaled ( 0.8f ) ;
for ( int extruder_idx = 0 ; extruder_idx < m_extruders_colors . size ( ) ; extruder_idx + + ) {
const std : : array < float , 4 > & extruder_color = m_extruders_colors [ extruder_idx ] ;
ImVec4 color_vec ( extruder_color [ 0 ] , extruder_color [ 1 ] , extruder_color [ 2 ] , extruder_color [ 3 ] ) ;
std : : string color_label = std : : string ( " ##extruder color " ) + std : : to_string ( extruder_idx ) ;
std : : string item_text = std : : to_string ( extruder_idx + 1 ) ;
const ImVec2 label_size = ImGui : : CalcTextSize ( item_text . c_str ( ) , NULL , true ) ;
const ImVec2 button_size ( max_label_size . x + m_imgui - > scaled ( 0.5f ) , 0.f ) ;
float button_offset = start_pos_x ;
if ( extruder_idx % max_filament_items_per_line ! = 0 ) {
button_offset + = filament_item_width * ( extruder_idx % max_filament_items_per_line ) ;
ImGui : : SameLine ( button_offset ) ;
}
// draw filament background
ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip ;
if ( m_selected_extruder_idx ! = extruder_idx ) flags | = ImGuiColorEditFlags_NoBorder ;
2022-07-22 09:46:10 +00:00
# ifdef __APPLE__
ImGui : : PushStyleColor ( ImGuiCol_FrameBg , ImVec4 ( 0.4f , 0.4f , 0.4f , 1.0f ) ) ;
ImGui : : PushStyleVar ( ImGuiStyleVar_FrameBorderSize , 0.0f ) ;
bool color_picked = ImGui : : ColorButton ( color_label . c_str ( ) , color_vec , flags , button_size ) ;
ImGui : : PopStyleVar ( 1 ) ;
ImGui : : PopStyleColor ( 1 ) ;
# else
bool color_picked = ImGui : : ColorButton ( color_label . c_str ( ) , color_vec , flags , button_size ) ;
# endif
2022-07-15 15:37:19 +00:00
color_button_high = ImGui : : GetCursorPos ( ) . y - color_button - 2.0 ;
if ( color_picked ) { m_selected_extruder_idx = extruder_idx ; }
if ( extruder_idx < 9 & & ImGui : : IsItemHovered ( ) ) m_imgui - > tooltip ( _L ( " Shortcut Key " ) + std : : to_string ( extruder_idx + 1 ) , max_tooltip_width ) ;
// draw filament id
float gray = 0.299 * extruder_color [ 0 ] + 0.587 * extruder_color [ 1 ] + 0.114 * extruder_color [ 2 ] ;
ImGui : : SameLine ( button_offset + ( button_size . x - label_size . x ) / 2.f ) ;
if ( gray * 255.f < 80.f )
ImGui : : TextColored ( ImVec4 ( 1.0f , 1.0f , 1.0f , 1.0f ) , item_text . c_str ( ) ) ;
else
ImGui : : TextColored ( ImVec4 ( 0.0f , 0.0f , 0.0f , 1.0f ) , item_text . c_str ( ) ) ;
}
//ImGui::NewLine();
ImGui : : Dummy ( ImVec2 ( 0.0f , ImGui : : GetFontSize ( ) * 0.1 ) ) ;
m_imgui - > text ( m_desc . at ( " tool_type " ) ) ;
2022-07-23 08:46:17 +00:00
std : : array < wchar_t , 6 > tool_icons = { ImGui : : CircleButtonIcon , ImGui : : SphereButtonIcon , ImGui : : TriangleButtonIcon , ImGui : : HeightRangeIcon , ImGui : : FillButtonIcon , ImGui : : GapFillIcon } ;
2022-07-22 09:46:10 +00:00
std : : array < wxString , 6 > tool_tips = { _L ( " Circle " ) , _L ( " Sphere " ) , _L ( " Triangle " ) , _L ( " Height Range " ) , _L ( " Fill " ) , _L ( " Gap Fill " ) } ;
2022-07-15 15:37:19 +00:00
for ( int i = 0 ; i < tool_icons . size ( ) ; i + + ) {
std : : string str_label = std : : string ( " ## " ) ;
std : : wstring btn_name = tool_icons [ i ] + boost : : nowide : : widen ( str_label ) ;
if ( i ! = 0 ) ImGui : : SameLine ( ( empty_button_width + m_imgui - > scaled ( 1.75f ) ) * i + m_imgui - > scaled ( 0.5f ) ) ;
if ( m_current_tool = = tool_icons [ i ] ) {
ImGui : : PushStyleColor ( ImGuiCol_Button , ImVec4 ( 0.81f , 0.81f , 0.81f , 1.0f ) ) ; // r, g, b, a
ImGui : : PushStyleColor ( ImGuiCol_ButtonHovered , ImVec4 ( 0.81f , 0.81f , 0.81f , 1.0f ) ) ;
ImGui : : PushStyleColor ( ImGuiCol_ButtonActive , ImVec4 ( 0.81f , 0.81f , 0.81f , 1.0f ) ) ;
}
ImGui : : PushStyleVar ( ImGuiStyleVar_FrameBorderSize , 0.0 ) ;
bool btn_clicked = ImGui : : Button ( into_u8 ( btn_name ) . c_str ( ) ) ;
ImGui : : PopStyleVar ( 1 ) ;
if ( m_current_tool = = tool_icons [ i ] ) ImGui : : PopStyleColor ( 3 ) ;
if ( btn_clicked & & m_current_tool ! = tool_icons [ i ] ) {
m_current_tool = tool_icons [ i ] ;
for ( auto & triangle_selector : m_triangle_selectors ) {
triangle_selector - > seed_fill_unselect_all_triangles ( ) ;
triangle_selector - > request_update_render_data ( ) ;
}
}
if ( ImGui : : IsItemHovered ( ) ) {
m_imgui - > tooltip ( tool_tips [ i ] , max_tooltip_width ) ;
}
}
ImGui : : Dummy ( ImVec2 ( 0.0f , ImGui : : GetFontSize ( ) * 0.1 ) ) ;
if ( m_current_tool ! = old_tool )
this - > tool_changed ( old_tool , m_current_tool ) ;
2022-07-22 09:46:10 +00:00
if ( m_current_tool = = ImGui : : CircleButtonIcon | | m_current_tool = = ImGui : : SphereButtonIcon ) {
if ( m_current_tool = = ImGui : : CircleButtonIcon )
m_cursor_type = TriangleSelector : : CursorType : : CIRCLE ;
else
m_cursor_type = TriangleSelector : : CursorType : : SPHERE ;
2022-07-15 15:37:19 +00:00
m_tool_type = ToolType : : BRUSH ;
ImGui : : AlignTextToFramePadding ( ) ;
m_imgui - > text ( m_desc . at ( " cursor_size " ) ) ;
2022-07-22 09:46:10 +00:00
ImGui : : SameLine ( circle_max_width ) ;
ImGui : : PushItemWidth ( window_width - circle_max_width - slider_width_times * slider_icon_width ) ;
2022-07-15 15:37:19 +00:00
m_imgui - > bbl_slider_float_style ( " ##cursor_radius " , & m_cursor_radius , CursorRadiusMin , CursorRadiusMax , " %.2f " , 1.0f , true ) ;
ImGui : : SameLine ( window_width - slider_icon_width ) ;
ImGui : : PushItemWidth ( 1.5 * slider_icon_width ) ;
ImGui : : BBLDragFloat ( " ##cursor_radius_input " , & m_cursor_radius , 0.05f , 0.0f , 0.0f , " %.2f " ) ;
2022-07-22 09:46:10 +00:00
ImGui : : Separator ( ) ;
2022-07-15 15:37:19 +00:00
ImGui : : AlignTextToFramePadding ( ) ;
2022-07-22 09:46:10 +00:00
m_imgui - > text ( m_desc . at ( " clipping_of_view " ) ) ;
auto clp_dist = float ( m_c - > object_clipper ( ) - > get_position ( ) ) ;
ImGui : : SameLine ( circle_max_width ) ;
ImGui : : PushItemWidth ( window_width - circle_max_width - slider_width_times * slider_icon_width ) ;
bool slider_clp_dist = m_imgui - > bbl_slider_float_style ( " ##clp_dist " , & clp_dist , 0.f , 1.f , " %.2f " , 1.0f , true ) ;
2022-07-15 15:37:19 +00:00
ImGui : : SameLine ( window_width - slider_icon_width ) ;
ImGui : : PushItemWidth ( 1.5 * slider_icon_width ) ;
2022-07-22 09:46:10 +00:00
bool b_clp_dist_input = ImGui : : BBLDragFloat ( " ##clp_dist_input " , & clp_dist , 0.05f , 0.0f , 0.0f , " %.2f " ) ;
if ( slider_clp_dist | | b_clp_dist_input ) { m_c - > object_clipper ( ) - > set_position ( clp_dist , true ) ; }
2022-07-15 15:37:19 +00:00
} else if ( m_current_tool = = ImGui : : TriangleButtonIcon ) {
m_cursor_type = TriangleSelector : : CursorType : : POINTER ;
m_tool_type = ToolType : : BRUSH ;
2022-07-22 09:46:10 +00:00
ImGui : : AlignTextToFramePadding ( ) ;
m_imgui - > text ( m_desc . at ( " clipping_of_view " ) ) ;
auto clp_dist = float ( m_c - > object_clipper ( ) - > get_position ( ) ) ;
ImGui : : SameLine ( clipping_slider_left ) ;
ImGui : : PushItemWidth ( window_width - clipping_slider_left - slider_width_times * slider_icon_width ) ;
bool slider_clp_dist = m_imgui - > bbl_slider_float_style ( " ##clp_dist " , & clp_dist , 0.f , 1.f , " %.2f " , 1.0f , true ) ;
ImGui : : SameLine ( window_width - slider_icon_width ) ;
ImGui : : PushItemWidth ( 1.5 * slider_icon_width ) ;
bool b_clp_dist_input = ImGui : : BBLDragFloat ( " ##clp_dist_input " , & clp_dist , 0.05f , 0.0f , 0.0f , " %.2f " ) ;
if ( slider_clp_dist | | b_clp_dist_input ) { m_c - > object_clipper ( ) - > set_position ( clp_dist , true ) ; }
2022-07-15 15:37:19 +00:00
} else if ( m_current_tool = = ImGui : : FillButtonIcon ) {
m_cursor_type = TriangleSelector : : CursorType : : POINTER ;
m_imgui - > bbl_checkbox ( m_desc [ " edge_detection " ] , m_detect_geometry_edge ) ;
m_tool_type = ToolType : : BUCKET_FILL ;
if ( m_detect_geometry_edge ) {
ImGui : : AlignTextToFramePadding ( ) ;
m_imgui - > text ( m_desc [ " smart_fill_angle " ] + " : " ) ;
std : : string format_str = std : : string ( " %.f " ) + I18N : : translate_utf8 ( " ° " , " Face angle threshold, "
" placed after the number with no whitespace in between. " ) ;
ImGui : : SameLine ( sliders_left_width ) ;
ImGui : : PushItemWidth ( window_width - sliders_left_width - slider_width_times * slider_icon_width ) ;
if ( m_imgui - > bbl_slider_float_style ( " ##smart_fill_angle " , & m_smart_fill_angle , SmartFillAngleMin , SmartFillAngleMax , format_str . data ( ) , 1.0f , true ) )
for ( auto & triangle_selector : m_triangle_selectors ) {
triangle_selector - > seed_fill_unselect_all_triangles ( ) ;
triangle_selector - > request_update_render_data ( ) ;
}
ImGui : : SameLine ( window_width - slider_icon_width ) ;
ImGui : : PushItemWidth ( 1.5 * slider_icon_width ) ;
ImGui : : BBLDragFloat ( " ##smart_fill_angle_input " , & m_smart_fill_angle , 0.05f , 0.0f , 0.0f , " %.2f " ) ;
} else {
// set to negative value to disable edge detection
m_smart_fill_angle = - 1.f ;
}
2022-07-22 09:46:10 +00:00
ImGui : : Separator ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
m_imgui - > text ( m_desc . at ( " clipping_of_view " ) ) ;
auto clp_dist = float ( m_c - > object_clipper ( ) - > get_position ( ) ) ;
ImGui : : SameLine ( sliders_left_width ) ;
ImGui : : PushItemWidth ( window_width - sliders_left_width - slider_width_times * slider_icon_width ) ;
bool slider_clp_dist = m_imgui - > bbl_slider_float_style ( " ##clp_dist " , & clp_dist , 0.f , 1.f , " %.2f " , 1.0f , true ) ;
ImGui : : SameLine ( window_width - slider_icon_width ) ;
ImGui : : PushItemWidth ( 1.5 * slider_icon_width ) ;
bool b_clp_dist_input = ImGui : : BBLDragFloat ( " ##clp_dist_input " , & clp_dist , 0.05f , 0.0f , 0.0f , " %.2f " ) ;
if ( slider_clp_dist | | b_clp_dist_input ) { m_c - > object_clipper ( ) - > set_position ( clp_dist , true ) ; }
2022-07-15 15:37:19 +00:00
} else if ( m_current_tool = = ImGui : : HeightRangeIcon ) {
m_tool_type = ToolType : : BRUSH ;
m_cursor_type = TriangleSelector : : CursorType : : HEIGHT_RANGE ;
ImGui : : AlignTextToFramePadding ( ) ;
m_imgui - > text ( m_desc [ " height_range " ] + " : " ) ;
2022-07-22 09:46:10 +00:00
ImGui : : SameLine ( height_max_width ) ;
ImGui : : PushItemWidth ( window_width - height_max_width - slider_width_times * slider_icon_width ) ;
2022-07-15 15:37:19 +00:00
std : : string format_str = std : : string ( " %.2f " ) + I18N : : translate_utf8 ( " mm " , " Heigh range, " " Facet in [cursor z, cursor z + height] will be selected. " ) ;
m_imgui - > bbl_slider_float_style ( " ##cursor_height " , & m_cursor_height , CursorHeightMin , CursorHeightMax , format_str . data ( ) , 1.0f , true ) ;
ImGui : : SameLine ( window_width - slider_icon_width ) ;
ImGui : : PushItemWidth ( 1.5 * slider_icon_width ) ;
ImGui : : BBLDragFloat ( " ##cursor_height_input " , & m_cursor_height , 0.05f , 0.0f , 0.0f , " %.2f " ) ;
ImGui : : Separator ( ) ;
ImGui : : AlignTextToFramePadding ( ) ;
m_imgui - > text ( m_desc . at ( " clipping_of_view " ) ) ;
auto clp_dist = float ( m_c - > object_clipper ( ) - > get_position ( ) ) ;
2022-07-22 09:46:10 +00:00
ImGui : : SameLine ( height_max_width ) ;
ImGui : : PushItemWidth ( window_width - height_max_width - slider_width_times * slider_icon_width ) ;
2022-07-15 15:37:19 +00:00
bool slider_clp_dist = m_imgui - > bbl_slider_float_style ( " ##clp_dist " , & clp_dist , 0.f , 1.f , " %.2f " , 1.0f , true ) ;
ImGui : : SameLine ( window_width - slider_icon_width ) ;
ImGui : : PushItemWidth ( 1.5 * slider_icon_width ) ;
bool b_clp_dist_input = ImGui : : BBLDragFloat ( " ##clp_dist_input " , & clp_dist , 0.05f , 0.0f , 0.0f , " %.2f " ) ;
if ( slider_clp_dist | | b_clp_dist_input ) { m_c - > object_clipper ( ) - > set_position ( clp_dist , true ) ; }
}
2022-07-23 08:46:17 +00:00
else if ( m_current_tool = = ImGui : : GapFillIcon ) {
m_tool_type = ToolType : : GAP_FILL ;
2022-07-22 09:46:10 +00:00
m_cursor_type = TriangleSelector : : CursorType : : POINTER ;
ImGui : : AlignTextToFramePadding ( ) ;
2022-07-23 08:46:17 +00:00
m_imgui - > text ( m_desc [ " gap_area " ] + " : " ) ;
ImGui : : SameLine ( gap_area_slider_left ) ;
ImGui : : PushItemWidth ( window_width - gap_area_slider_left - slider_width_times * slider_icon_width ) ;
2022-07-22 09:46:10 +00:00
std : : string format_str = std : : string ( " %.2f " ) + I18N : : translate_utf8 ( " " , " Triangle patch area threshold, " " triangle patch will be merged to neighbor if its area is less than threshold " ) ;
2022-07-23 08:46:17 +00:00
m_imgui - > bbl_slider_float_style ( " ##gap_area " , & TriangleSelectorPatch : : gap_area , TriangleSelectorPatch : : GapAreaMin , TriangleSelectorPatch : : GapAreaMax , format_str . data ( ) , 1.0f , true ) ;
2022-07-22 09:46:10 +00:00
ImGui : : SameLine ( window_width - slider_icon_width ) ;
ImGui : : PushItemWidth ( 1.5 * slider_icon_width ) ;
2022-07-23 08:46:17 +00:00
ImGui : : BBLDragFloat ( " ##gap_area_input " , & TriangleSelectorPatch : : gap_area , 0.05f , 0.0f , 0.0f , " %.2f " ) ;
2022-07-22 09:46:10 +00:00
}
2022-07-15 15:37:19 +00:00
ImGui : : Separator ( ) ;
ImGui : : PushStyleVar ( ImGuiStyleVar_ItemSpacing , ImVec2 ( 6.0f , 10.0f ) ) ;
float get_cur_y = ImGui : : GetContentRegionMax ( ) . y + ImGui : : GetFrameHeight ( ) + y ;
show_tooltip_information ( caption_max , x , get_cur_y ) ;
2022-07-25 01:50:52 +00:00
float f_scale = m_parent . get_gizmos_manager ( ) . get_layout_scale ( ) ;
ImGui : : PushStyleVar ( ImGuiStyleVar_FramePadding , ImVec2 ( 6.0f , 4.0f * f_scale ) ) ;
2022-07-15 15:37:19 +00:00
ImGui : : SameLine ( ) ;
2022-07-23 08:46:17 +00:00
if ( m_current_tool = = ImGui : : GapFillIcon ) {
if ( m_imgui - > button ( m_desc . at ( " perform " ) ) ) {
Plater : : TakeSnapshot snapshot ( wxGetApp ( ) . plater ( ) , " Gap fill " , UndoRedo : : SnapshotType : : GizmoAction ) ;
2022-07-15 15:37:19 +00:00
for ( int i = 0 ; i < m_triangle_selectors . size ( ) ; i + + ) {
TriangleSelectorPatch * ts_mm = dynamic_cast < TriangleSelectorPatch * > ( m_triangle_selectors [ i ] . get ( ) ) ;
ts_mm - > update_selector_triangles ( ) ;
ts_mm - > request_update_render_data ( true ) ;
}
update_model_object ( ) ;
m_parent . set_as_dirty ( ) ;
}
ImGui : : SameLine ( ) ;
}
if ( m_imgui - > button ( m_desc . at ( " remove_all " ) ) ) {
Plater : : TakeSnapshot snapshot ( wxGetApp ( ) . plater ( ) , " Reset selection " , UndoRedo : : SnapshotType : : GizmoAction ) ;
ModelObject * mo = m_c - > selection_info ( ) - > model_object ( ) ;
int idx = - 1 ;
for ( ModelVolume * mv : mo - > volumes )
if ( mv - > is_model_part ( ) ) {
+ + idx ;
m_triangle_selectors [ idx ] - > reset ( ) ;
m_triangle_selectors [ idx ] - > request_update_render_data ( true ) ;
}
update_model_object ( ) ;
m_parent . set_as_dirty ( ) ;
}
ImGui : : PopStyleVar ( 2 ) ;
GizmoImguiEnd ( ) ;
// BBS
ImGui : : PopStyleVar ( 1 ) ;
ImGuiWrapper : : pop_toolbar_style ( ) ;
}
void GLGizmoMmuSegmentation : : update_model_object ( )
{
bool updated = false ;
ModelObject * mo = m_c - > selection_info ( ) - > model_object ( ) ;
int idx = - 1 ;
for ( ModelVolume * mv : mo - > volumes ) {
if ( ! mv - > is_model_part ( ) )
continue ;
+ + idx ;
updated | = mv - > mmu_segmentation_facets . set ( * m_triangle_selectors [ idx ] . get ( ) ) ;
}
if ( updated ) {
const ModelObjectPtrs & mos = wxGetApp ( ) . model ( ) . objects ;
wxGetApp ( ) . obj_list ( ) - > update_info_items ( std : : find ( mos . begin ( ) , mos . end ( ) , mo ) - mos . begin ( ) ) ;
m_parent . post_event ( SimpleEvent ( EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS ) ) ;
}
}
void GLGizmoMmuSegmentation : : init_model_triangle_selectors ( )
{
const ModelObject * mo = m_c - > selection_info ( ) - > model_object ( ) ;
m_triangle_selectors . clear ( ) ;
m_volumes_extruder_idxs . clear ( ) ;
// Don't continue when extruders colors are not initialized
if ( m_extruders_colors . empty ( ) )
return ;
// BBS: Don't continue when model object is null
if ( mo = = nullptr )
return ;
for ( const ModelVolume * mv : mo - > volumes ) {
if ( ! mv - > is_model_part ( ) )
continue ;
int extruder_idx = ( mv - > extruder_id ( ) > 0 ) ? mv - > extruder_id ( ) - 1 : 0 ;
std : : vector < std : : array < float , 4 > > ebt_colors ;
ebt_colors . push_back ( m_extruders_colors [ size_t ( extruder_idx ) ] ) ;
ebt_colors . insert ( ebt_colors . end ( ) , m_extruders_colors . begin ( ) , m_extruders_colors . end ( ) ) ;
// This mesh does not account for the possible Z up SLA offset.
const TriangleMesh * mesh = & mv - > mesh ( ) ;
m_triangle_selectors . emplace_back ( std : : make_unique < TriangleSelectorPatch > ( * mesh , ebt_colors , 0.2 ) ) ;
// Reset of TriangleSelector is done inside TriangleSelectorMmGUI's constructor, so we don't need it to perform it again in deserialize().
m_triangle_selectors . back ( ) - > deserialize ( mv - > mmu_segmentation_facets . get_data ( ) , false ) ;
m_triangle_selectors . back ( ) - > request_update_render_data ( ) ;
m_volumes_extruder_idxs . push_back ( mv - > extruder_id ( ) ) ;
}
}
void GLGizmoMmuSegmentation : : update_triangle_selectors_colors ( )
{
for ( int i = 0 ; i < m_triangle_selectors . size ( ) ; i + + ) {
TriangleSelectorPatch * selector = dynamic_cast < TriangleSelectorPatch * > ( m_triangle_selectors [ i ] . get ( ) ) ;
int extruder_idx = m_volumes_extruder_idxs [ i ] ;
int extruder_color_idx = std : : max ( 0 , extruder_idx - 1 ) ;
std : : vector < std : : array < float , 4 > > ebt_colors ;
ebt_colors . push_back ( m_extruders_colors [ extruder_color_idx ] ) ;
ebt_colors . insert ( ebt_colors . end ( ) , m_extruders_colors . begin ( ) , m_extruders_colors . end ( ) ) ;
selector - > set_ebt_colors ( ebt_colors ) ;
}
}
void GLGizmoMmuSegmentation : : update_from_model_object ( bool first_update )
{
wxBusyCursor wait ;
// Extruder colors need to be reloaded before calling init_model_triangle_selectors to render painted triangles
// using colors from loaded 3MF and not from printer profile in Slicer.
if ( int prev_extruders_count = int ( m_extruders_colors . size ( ) ) ;
prev_extruders_count ! = wxGetApp ( ) . filaments_cnt ( ) | | get_extruders_colors ( ) ! = m_extruders_colors )
this - > init_extruders_data ( ) ;
this - > init_model_triangle_selectors ( ) ;
}
void GLGizmoMmuSegmentation : : tool_changed ( wchar_t old_tool , wchar_t new_tool )
{
2022-07-23 08:46:17 +00:00
if ( ( old_tool = = ImGui : : GapFillIcon & & new_tool = = ImGui : : GapFillIcon ) | |
( old_tool ! = ImGui : : GapFillIcon & & new_tool ! = ImGui : : GapFillIcon ) )
2022-07-15 15:37:19 +00:00
return ;
for ( auto & selector_ptr : m_triangle_selectors ) {
TriangleSelectorPatch * tsp = dynamic_cast < TriangleSelectorPatch * > ( selector_ptr . get ( ) ) ;
2022-07-23 08:46:17 +00:00
tsp - > set_filter_state ( new_tool = = ImGui : : GapFillIcon ) ;
2022-07-15 15:37:19 +00:00
}
}
PainterGizmoType GLGizmoMmuSegmentation : : get_painter_type ( ) const
{
return PainterGizmoType : : MMU_SEGMENTATION ;
}
// BBS
std : : array < float , 4 > GLGizmoMmuSegmentation : : get_cursor_hover_color ( ) const
{
if ( m_selected_extruder_idx < m_extruders_colors . size ( ) )
return m_extruders_colors [ m_selected_extruder_idx ] ;
else
return m_extruders_colors [ 0 ] ;
}
2022-08-02 12:27:45 +00:00
void GLGizmoMmuSegmentation : : on_set_state ( )
{
GLGizmoPainterBase : : on_set_state ( ) ;
if ( get_state ( ) = = Off ) {
ModelObject * mo = m_c - > selection_info ( ) - > model_object ( ) ;
if ( mo ) Slic3r : : save_object_mesh ( * mo ) ;
}
}
2022-07-15 15:37:19 +00:00
wxString GLGizmoMmuSegmentation : : handle_snapshot_action_name ( bool shift_down , GLGizmoPainterBase : : Button button_down ) const
{
wxString action_name ;
if ( shift_down )
action_name = _L ( " Remove painted color " ) ;
else {
action_name = GUI : : format ( _L ( " Painted using: Filament %1% " ) , m_selected_extruder_idx ) ;
}
return action_name ;
}
void GLMmSegmentationGizmo3DScene : : release_geometry ( ) {
if ( this - > vertices_VBO_id ) {
glsafe ( : : glDeleteBuffers ( 1 , & this - > vertices_VBO_id ) ) ;
this - > vertices_VBO_id = 0 ;
}
for ( auto & triangle_indices_VBO_id : triangle_indices_VBO_ids ) {
glsafe ( : : glDeleteBuffers ( 1 , & triangle_indices_VBO_id ) ) ;
triangle_indices_VBO_id = 0 ;
}
this - > clear ( ) ;
}
void GLMmSegmentationGizmo3DScene : : render ( size_t triangle_indices_idx ) const
{
assert ( triangle_indices_idx < this - > triangle_indices_VBO_ids . size ( ) ) ;
assert ( this - > triangle_patches . size ( ) = = this - > triangle_indices_VBO_ids . size ( ) ) ;
assert ( this - > vertices_VBO_id ! = 0 ) ;
assert ( this - > triangle_indices_VBO_ids [ triangle_indices_idx ] ! = 0 ) ;
glsafe ( : : glBindBuffer ( GL_ARRAY_BUFFER , this - > vertices_VBO_id ) ) ;
glsafe ( : : glVertexPointer ( 3 , GL_FLOAT , 3 * sizeof ( float ) , ( const void * ) ( 0 * sizeof ( float ) ) ) ) ;
glsafe ( : : glEnableClientState ( GL_VERTEX_ARRAY ) ) ;
// Render using the Vertex Buffer Objects.
if ( this - > triangle_indices_sizes [ triangle_indices_idx ] > 0 ) {
glsafe ( : : glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , this - > triangle_indices_VBO_ids [ triangle_indices_idx ] ) ) ;
glsafe ( : : glDrawElements ( GL_TRIANGLES , GLsizei ( this - > triangle_indices_sizes [ triangle_indices_idx ] ) , GL_UNSIGNED_INT , nullptr ) ) ;
glsafe ( glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , 0 ) ) ;
}
glsafe ( : : glDisableClientState ( GL_VERTEX_ARRAY ) ) ;
glsafe ( : : glBindBuffer ( GL_ARRAY_BUFFER , 0 ) ) ;
}
void GLMmSegmentationGizmo3DScene : : finalize_vertices ( )
{
assert ( this - > vertices_VBO_id = = 0 ) ;
if ( ! this - > vertices . empty ( ) ) {
glsafe ( : : glGenBuffers ( 1 , & this - > vertices_VBO_id ) ) ;
glsafe ( : : glBindBuffer ( GL_ARRAY_BUFFER , this - > vertices_VBO_id ) ) ;
glsafe ( : : glBufferData ( GL_ARRAY_BUFFER , this - > vertices . size ( ) * sizeof ( float ) , this - > vertices . data ( ) , GL_STATIC_DRAW ) ) ;
glsafe ( : : glBindBuffer ( GL_ARRAY_BUFFER , 0 ) ) ;
this - > vertices . clear ( ) ;
}
}
void GLMmSegmentationGizmo3DScene : : finalize_triangle_indices ( )
{
triangle_indices_VBO_ids . resize ( this - > triangle_patches . size ( ) ) ;
triangle_indices_sizes . resize ( this - > triangle_patches . size ( ) ) ;
assert ( std : : all_of ( triangle_indices_VBO_ids . cbegin ( ) , triangle_indices_VBO_ids . cend ( ) , [ ] ( const auto & ti_VBO_id ) { return ti_VBO_id = = 0 ; } ) ) ;
for ( size_t buffer_idx = 0 ; buffer_idx < this - > triangle_patches . size ( ) ; + + buffer_idx ) {
std : : vector < int > & triangle_indices = this - > triangle_patches [ buffer_idx ] . triangle_indices ;
triangle_indices_sizes [ buffer_idx ] = triangle_indices . size ( ) ;
if ( ! triangle_indices . empty ( ) ) {
glsafe ( : : glGenBuffers ( 1 , & this - > triangle_indices_VBO_ids [ buffer_idx ] ) ) ;
glsafe ( : : glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , this - > triangle_indices_VBO_ids [ buffer_idx ] ) ) ;
glsafe ( : : glBufferData ( GL_ELEMENT_ARRAY_BUFFER , triangle_indices . size ( ) * sizeof ( int ) , triangle_indices . data ( ) , GL_STATIC_DRAW ) ) ;
glsafe ( : : glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , 0 ) ) ;
triangle_indices . clear ( ) ;
}
}
}
} // namespace Slic3r