mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge branch 'lm_sla_supports_auto2' of https://github.com/prusa3d/Slic3r into lm_sla_supports_auto2
This commit is contained in:
		
						commit
						09cce95181
					
				
					 5 changed files with 338 additions and 131 deletions
				
			
		|  | @ -395,7 +395,7 @@ void SLAAutoSupports::uniformly_cover(const ExPolygon& island, Structure& struct | |||
| 
 | ||||
|     assert(! poisson_samples.empty()); | ||||
|     for (const Vec2f &pt : poisson_samples) { | ||||
|         m_output.emplace_back(float(pt(0)), float(pt(1)), structure.height, 0.4f, is_new_island); | ||||
|         m_output.emplace_back(float(pt(0)), float(pt(1)), structure.height, 0.2f, is_new_island); | ||||
|         structure.supports_force += m_config.support_force; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -3430,24 +3430,18 @@ void GLCanvas3D::Gizmos::set_sla_support_data(ModelObject* model_object, const G | |||
|         reinterpret_cast<GLGizmoSlaSupports*>(it->second)->set_sla_support_data(model_object, selection); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Gizmos::clicked_on_object(const Vec2d& mouse_position) | ||||
| 
 | ||||
| // Returns true if the gizmo used the event to do something, false otherwise.
 | ||||
| bool GLCanvas3D::Gizmos::mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down) | ||||
| { | ||||
|     if (!m_enabled) | ||||
|         return; | ||||
|         return false; | ||||
| 
 | ||||
|     GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); | ||||
|     if (it != m_gizmos.end()) | ||||
|         reinterpret_cast<GLGizmoSlaSupports*>(it->second)->clicked_on_object(mouse_position); | ||||
| } | ||||
|         return reinterpret_cast<GLGizmoSlaSupports*>(it->second)->mouse_event(action, mouse_position, shift_down); | ||||
| 
 | ||||
| void GLCanvas3D::Gizmos::delete_current_grabber(bool delete_all) | ||||
| { | ||||
|     if (!m_enabled) | ||||
|         return; | ||||
| 
 | ||||
|     GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); | ||||
|     if (it != m_gizmos.end()) | ||||
|         reinterpret_cast<GLGizmoSlaSupports*>(it->second)->delete_current_point(delete_all); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Gizmos::render_current_gizmo(const GLCanvas3D::Selection& selection) const | ||||
|  | @ -5114,6 +5108,7 @@ void GLCanvas3D::bind_event_handlers() | |||
|         m_canvas->Bind(wxEVT_SIZE, &GLCanvas3D::on_size, this); | ||||
|         m_canvas->Bind(wxEVT_IDLE, &GLCanvas3D::on_idle, this); | ||||
|         m_canvas->Bind(wxEVT_CHAR, &GLCanvas3D::on_char, this); | ||||
|         m_canvas->Bind(wxEVT_KEY_UP, &GLCanvas3D::on_key_up, this); | ||||
|         m_canvas->Bind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this); | ||||
|         m_canvas->Bind(wxEVT_TIMER, &GLCanvas3D::on_timer, this); | ||||
|         m_canvas->Bind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this); | ||||
|  | @ -5139,6 +5134,7 @@ void GLCanvas3D::unbind_event_handlers() | |||
|         m_canvas->Unbind(wxEVT_SIZE, &GLCanvas3D::on_size, this); | ||||
|         m_canvas->Unbind(wxEVT_IDLE, &GLCanvas3D::on_idle, this); | ||||
|         m_canvas->Unbind(wxEVT_CHAR, &GLCanvas3D::on_char, this); | ||||
|         m_canvas->Unbind(wxEVT_KEY_UP, &GLCanvas3D::on_key_up, this); | ||||
|         m_canvas->Unbind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this); | ||||
|         m_canvas->Unbind(wxEVT_TIMER, &GLCanvas3D::on_timer, this); | ||||
|         m_canvas->Unbind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this); | ||||
|  | @ -5182,7 +5178,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) | |||
|         switch (keyCode) { | ||||
|         case 'a': | ||||
|         case 'A': | ||||
|         case WXK_CONTROL_A: post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); break; | ||||
|         case WXK_CONTROL_A: | ||||
|             if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::SelectAll)) // Sla gizmo selects all support points
 | ||||
|                 m_dirty = true; | ||||
|             else | ||||
|                 post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); | ||||
|         break; | ||||
| #ifdef __APPLE__ | ||||
|         case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead.
 | ||||
| #else /* __APPLE__ */ | ||||
|  | @ -5203,7 +5204,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) | |||
| #else /* __APPLE__ */ | ||||
| 		case WXK_DELETE: | ||||
| #endif /* __APPLE__ */ | ||||
|                   post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; | ||||
|                   if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::Delete)) | ||||
|                       m_dirty = true; | ||||
|                   else | ||||
|                       post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); | ||||
|                   break; | ||||
| 
 | ||||
| 		case '0': { select_view("iso"); break; } | ||||
|         case '1': { select_view("top"); break; } | ||||
|         case '2': { select_view("bottom"); break; } | ||||
|  | @ -5240,6 +5246,16 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::on_key_up(wxKeyEvent& evt) | ||||
| { | ||||
|     // see include/wx/defs.h enum wxKeyCode
 | ||||
|     int keyCode = evt.GetKeyCode(); | ||||
| 
 | ||||
|     // shift has been just released - SLA gizmo might want to close rectangular selection.
 | ||||
|     if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.mouse_event(SLAGizmoEventType::ShiftUp)) | ||||
|         m_dirty = true; | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) | ||||
| { | ||||
|     // Ignore the wheel events if the middle button is pressed.
 | ||||
|  | @ -5380,22 +5396,16 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|                 m_dirty = true; | ||||
|             } | ||||
|         } | ||||
| #if !ENABLE_IMGUI | ||||
|         else if ((m_gizmos.get_current_type() == Gizmos::SlaSupports) && gizmo_reset_rect_contains(*this, pos(0), pos(1))) | ||||
|         { | ||||
|             if (evt.LeftDown()) | ||||
|             { | ||||
|                 m_gizmos.delete_current_grabber(true); | ||||
|                 m_dirty = true; | ||||
|             } | ||||
|         } | ||||
| #endif // not ENABLE_IMGUI
 | ||||
|         else if (!m_selection.is_empty() && gizmos_overlay_contains_mouse) | ||||
|         { | ||||
|             m_gizmos.update_on_off_state(*this, m_mouse.position, m_selection); | ||||
|             _update_gizmos_data(); | ||||
|             m_dirty = true; | ||||
|         } | ||||
|         else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown() && m_gizmos.mouse_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) | ||||
|         { | ||||
|             // the gizmo got the event and took some action, there is no need to do anything more
 | ||||
|         } | ||||
|         else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse()) | ||||
|         { | ||||
|             _update_gizmos_data(); | ||||
|  | @ -5411,10 +5421,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
| 
 | ||||
|             m_dirty = true; | ||||
|         } | ||||
|         else if ((selected_object_idx != -1) && m_gizmos.grabber_contains_mouse() && evt.RightDown()) { | ||||
|         /*else if ((selected_object_idx != -1) && m_gizmos.grabber_contains_mouse() && evt.RightDown()) {
 | ||||
|             if (m_gizmos.get_current_type() == Gizmos::SlaSupports) | ||||
|                 m_gizmos.delete_current_grabber(); | ||||
|         } | ||||
|         }*/ | ||||
|         else if (view_toolbar_contains_mouse != -1) | ||||
|         { | ||||
|             if (m_view_toolbar != nullptr) | ||||
|  | @ -5519,7 +5529,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|             } | ||||
|         } | ||||
|     } | ||||
|     else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_overlay_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown) && (m_mouse.drag.move_volume_idx != -1)) | ||||
|     else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_overlay_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown) | ||||
|           && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != Gizmos::SlaSupports /* don't allow dragging objects with the Sla gizmo on */) | ||||
|     { | ||||
| #if ENABLE_MOVE_MIN_THRESHOLD | ||||
|         if (!m_mouse.drag.move_requires_threshold) | ||||
|  | @ -5579,6 +5590,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
| 
 | ||||
|         m_dirty = true; | ||||
|     } | ||||
|     else if (evt.Dragging() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown() && m_gizmos.mouse_event(SLAGizmoEventType::Dragging, Vec2d(pos(0), pos(1)), evt.ShiftDown())) | ||||
|     { | ||||
|         // the gizmo got the event and took some action, no need to do anything more here
 | ||||
|         m_dirty = true; | ||||
|     } | ||||
|     else if (evt.Dragging() && !gizmos_overlay_contains_mouse) | ||||
|     { | ||||
|         m_mouse.dragging = true; | ||||
|  | @ -5634,6 +5650,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|             _stop_timer(); | ||||
|             m_layers_editing.accept_changes(*this); | ||||
|         } | ||||
|         else if (evt.LeftUp() && m_gizmos.get_current_type() == Gizmos::SlaSupports && !m_gizmos.is_dragging() | ||||
|               && !m_mouse.dragging && m_gizmos.mouse_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown())) | ||||
|         { | ||||
|             // the gizmo got the event and took some action, no need to do anything more
 | ||||
|         } | ||||
|         else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging) | ||||
|         { | ||||
|             m_regenerate_volumes = false; | ||||
|  | @ -5643,16 +5664,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|             // of the scene with the background processing data should be performed.
 | ||||
|             post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); | ||||
|         } | ||||
|         else if (evt.LeftUp() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_hover_volume_id != -1) | ||||
|         else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() | ||||
|               && !is_layers_editing_enabled() && m_gizmos.get_current_type() != Gizmos::SlaSupports) | ||||
|         { | ||||
|             int id = m_selection.get_object_idx(); | ||||
|             // SLA gizmo cannot be deselected by clicking in canvas area to avoid inadvertent unselection and losing manual changes
 | ||||
| 
 | ||||
|             if ((id != -1) && (m_model != nullptr)) { | ||||
|                 m_gizmos.clicked_on_object(Vec2d(pos(0), pos(1))); | ||||
|             } | ||||
|         } | ||||
|         else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() && !is_layers_editing_enabled()) | ||||
|         { | ||||
|             // deselect and propagate event through callback
 | ||||
|             if (!evt.ShiftDown() && m_picking_enabled && !m_toolbar_action_running && !m_mouse.ignore_up_event) | ||||
|             { | ||||
|  | @ -5685,10 +5701,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|                 do_rotate(); | ||||
|                 break; | ||||
|             } | ||||
|             case Gizmos::SlaSupports: | ||||
|                 // End of mouse dragging, update the SLAPrint/SLAPrintObjects with the new support points.
 | ||||
|                 post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
|             } | ||||
|  |  | |||
|  | @ -132,6 +132,17 @@ wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>); | |||
| wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); | ||||
| 
 | ||||
| // this describes events being passed from GLCanvas3D to SlaSupport gizmo
 | ||||
| enum class SLAGizmoEventType { | ||||
|     LeftDown = 1, | ||||
|     LeftUp, | ||||
|     Dragging, | ||||
|     Delete, | ||||
|     SelectAll, | ||||
|     ShiftUp | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| class GLCanvas3D | ||||
| { | ||||
|     struct GCodePreviewVolumeIndex | ||||
|  | @ -789,7 +800,7 @@ private: | |||
|         void set_flattening_data(const ModelObject* model_object); | ||||
| 
 | ||||
|         void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection); | ||||
|         void clicked_on_object(const Vec2d& mouse_position); | ||||
|         bool mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false); | ||||
|         void delete_current_grabber(bool delete_all = false); | ||||
| 
 | ||||
|         void render_current_gizmo(const Selection& selection) const; | ||||
|  | @ -1050,6 +1061,7 @@ public: | |||
|     void on_size(wxSizeEvent& evt); | ||||
|     void on_idle(wxIdleEvent& evt); | ||||
|     void on_char(wxKeyEvent& evt); | ||||
|     void on_key_up(wxKeyEvent& evt); | ||||
|     void on_mouse_wheel(wxMouseEvent& evt); | ||||
|     void on_timer(wxTimerEvent& evt); | ||||
|     void on_mouse(wxMouseEvent& evt); | ||||
|  |  | |||
|  | @ -1816,13 +1816,54 @@ void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const | |||
|     ::glEnable(GL_DEPTH_TEST); | ||||
| 
 | ||||
|     render_points(selection, false); | ||||
|     render_selection_rectangle(); | ||||
| 
 | ||||
| #if !ENABLE_IMGUI | ||||
|     render_tooltip_texture(); | ||||
| #endif // not ENABLE_IMGUI
 | ||||
| 
 | ||||
|     ::glDisable(GL_BLEND); | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSlaSupports::render_selection_rectangle() const | ||||
| { | ||||
|     if (!m_selection_rectangle_active) | ||||
|         return; | ||||
| 
 | ||||
|     ::glLineWidth(1.5f); | ||||
|     float render_color[3] = {1.f, 0.f, 0.f}; | ||||
|     ::glColor3fv(render_color); | ||||
| 
 | ||||
|     ::glPushAttrib(GL_TRANSFORM_BIT);   // remember current MatrixMode
 | ||||
| 
 | ||||
|     ::glMatrixMode(GL_MODELVIEW);       // cache modelview matrix and set to identity
 | ||||
|     ::glPushMatrix(); | ||||
|     ::glLoadIdentity(); | ||||
| 
 | ||||
|     ::glMatrixMode(GL_PROJECTION);      // cache projection matrix and set to identity
 | ||||
|     ::glPushMatrix(); | ||||
|     ::glLoadIdentity(); | ||||
| 
 | ||||
|     ::glOrtho(0.f, m_canvas_width, m_canvas_height, 0.f, -1.f, 1.f); // set projection matrix so that world coords = window coords
 | ||||
| 
 | ||||
|     // render the selection  rectangle (window coordinates):
 | ||||
|     ::glPushAttrib(GL_ENABLE_BIT); | ||||
|     ::glLineStipple(4, 0xAAAA); | ||||
|     ::glEnable(GL_LINE_STIPPLE); | ||||
| 
 | ||||
|     ::glBegin(GL_LINE_LOOP); | ||||
|     ::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f); | ||||
|     ::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f); | ||||
|     ::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f); | ||||
|     ::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f); | ||||
|     ::glEnd(); | ||||
|     ::glPopAttrib(); | ||||
| 
 | ||||
|     ::glPopMatrix();                // restore former projection matrix
 | ||||
|     ::glMatrixMode(GL_MODELVIEW); | ||||
|     ::glPopMatrix();                // restore former modelview matrix
 | ||||
|     ::glPopAttrib();                // restore former MatrixMode
 | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSlaSupports::on_render_for_picking(const GLCanvas3D::Selection& selection) const | ||||
| { | ||||
|  | @ -1854,7 +1895,8 @@ void GLGizmoSlaSupports::render_points(const GLCanvas3D::Selection& selection, b | |||
|     float render_color[3]; | ||||
|     for (int i = 0; i < (int)m_editing_mode_cache.size(); ++i) | ||||
|     { | ||||
|         const Vec3f& point_pos = m_editing_mode_cache[i].pos; | ||||
|         const Vec3f& point_pos = m_editing_mode_cache[i].first.pos; | ||||
|         const bool point_selected = m_editing_mode_cache[i].second; | ||||
|         // first precalculate the grabber position in world coordinates, so that the grabber
 | ||||
|         // is not scaled with the object (as it would be if rendered with current gl matrix).
 | ||||
|         Eigen::Matrix<GLfloat, 4, 4, Eigen::DontAlign> glmatrix; | ||||
|  | @ -1878,11 +1920,11 @@ void GLGizmoSlaSupports::render_points(const GLCanvas3D::Selection& selection, b | |||
|                 render_color[2] = picking_color_component(i); | ||||
|             } | ||||
|             else { // normal rendering
 | ||||
|                 bool supports_new_island = m_lock_unique_islands && m_editing_mode_cache[i].is_new_island; | ||||
|                 bool supports_new_island = m_lock_unique_islands && m_editing_mode_cache[i].first.is_new_island; | ||||
|                 if (m_editing_mode) { | ||||
|                     render_color[0] = supports_new_island ? 0.f : 1.f; | ||||
|                     render_color[1] = 0.f; | ||||
|                     render_color[2] = supports_new_island ? 1.f : 0.f; | ||||
|                     render_color[0] = point_selected ? 0.f : (supports_new_island ? 0.f : 1.f); | ||||
|                     render_color[1] = point_selected ? 1.f : 0.f; | ||||
|                     render_color[2] = point_selected ? 0.f : (supports_new_island ? 1.f : 0.f); | ||||
|                 } | ||||
|                 else | ||||
|                     for (unsigned char i=0; i<3; ++i) render_color[i] = 0.5f; | ||||
|  | @ -1893,7 +1935,7 @@ void GLGizmoSlaSupports::render_points(const GLCanvas3D::Selection& selection, b | |||
|         ::glPushMatrix(); | ||||
|         ::glLoadIdentity(); | ||||
|         ::glTranslated(grabber_world_position(0), grabber_world_position(1), grabber_world_position(2) + z_shift); | ||||
|         ::gluSphere(m_quadric, m_editing_mode_cache[i].head_front_radius, 64, 36); | ||||
|         ::gluSphere(m_quadric, m_editing_mode_cache[i].first.head_front_radius, 64, 36); | ||||
|         ::glPopMatrix(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -1941,7 +1983,9 @@ void GLGizmoSlaSupports::update_mesh() | |||
|     m_AABB.init(m_V, m_F); | ||||
| 
 | ||||
|     // we'll now reload support points (selection might have changed):
 | ||||
|     m_editing_mode_cache = m_model_object->sla_support_points; | ||||
|     m_editing_mode_cache.clear(); | ||||
|     for (const sla::SupportPoint& point : m_model_object->sla_support_points) | ||||
|         m_editing_mode_cache.push_back(std::make_pair(point, false)); | ||||
| } | ||||
| 
 | ||||
| Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) | ||||
|  | @ -1984,70 +2028,144 @@ Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) | |||
|     return bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2)); | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position) | ||||
| // Following function is called from GLCanvas3D to inform the gizmo about a mouse/keyboard event.
 | ||||
| // The gizmo has an opportunity to react - if it does, it should return true so that the Canvas3D is
 | ||||
| // aware that the event was reacted to and stops trying to make different sense of it. If the gizmo
 | ||||
| // concludes that the event was not intended for it, it should return false.
 | ||||
| bool GLGizmoSlaSupports::mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down) | ||||
| { | ||||
|     if (!m_editing_mode) | ||||
|         return false; | ||||
| 
 | ||||
|     // left down - show the selection rectangle:
 | ||||
|     if (action == SLAGizmoEventType::LeftDown && shift_down) { | ||||
|         if (m_hover_id == -1) { | ||||
|             m_selection_rectangle_active = true; | ||||
|             m_selection_rectangle_start_corner = mouse_position; | ||||
|             m_selection_rectangle_end_corner = mouse_position; | ||||
|             m_canvas_width = m_parent.get_canvas_size().get_width(); | ||||
|             m_canvas_height = m_parent.get_canvas_size().get_height(); | ||||
|         } | ||||
|         else | ||||
|             m_editing_mode_cache[m_hover_id].second = true; | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     // dragging the selection rectangle:
 | ||||
|     if (action == SLAGizmoEventType::Dragging && m_selection_rectangle_active) { | ||||
|         m_selection_rectangle_end_corner = mouse_position; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     // mouse up without selection rectangle - place point on the mesh:
 | ||||
|     if (action == SLAGizmoEventType::LeftUp && !m_selection_rectangle_active && !shift_down) { | ||||
|         if (m_ignore_up_event) { | ||||
|             m_ignore_up_event = false; | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         int instance_id = m_parent.get_selection().get_instance_idx(); | ||||
|         if (m_old_instance_id != instance_id) | ||||
|         { | ||||
|             bool something_selected = (m_old_instance_id != -1); | ||||
|             m_old_instance_id = instance_id; | ||||
|             if (something_selected) | ||||
|                 return false; | ||||
|         } | ||||
|         if (instance_id == -1) | ||||
|             return false; | ||||
| 
 | ||||
|         // Regardless of whether the user clicked the object or not, we will unselect all points:
 | ||||
|         for (unsigned int i=0; i<m_editing_mode_cache.size(); ++i) | ||||
|                     m_editing_mode_cache[i].second = false; | ||||
| 
 | ||||
|         Vec3f new_pos; | ||||
|         try { | ||||
|             new_pos = unproject_on_mesh(mouse_position); // this can throw - we don't want to create a new point in that case
 | ||||
|             m_editing_mode_cache.emplace_back(std::make_pair(sla::SupportPoint(new_pos, m_new_point_head_diameter/2.f, false), true)); | ||||
|         } | ||||
|         catch (...) {       // not clicked on object
 | ||||
|             return false;   // GLCanvas3D might want to deselect the gizmo
 | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     // left up with selection rectangle - select points inside the rectangle:
 | ||||
|     if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::ShiftUp) | ||||
|       && m_selection_rectangle_active) { | ||||
|         if (action == SLAGizmoEventType::ShiftUp) | ||||
|             m_ignore_up_event = true; | ||||
|         const Transform3d& instance_matrix = m_model_object->instances[m_active_instance]->get_transformation().get_matrix(); | ||||
|         GLint viewport[4]; | ||||
|         ::glGetIntegerv(GL_VIEWPORT, viewport); | ||||
|         GLdouble modelview_matrix[16]; | ||||
|         ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix); | ||||
|         GLdouble projection_matrix[16]; | ||||
|         ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix); | ||||
| 
 | ||||
|         const GLCanvas3D::Selection& selection = m_parent.get_selection(); | ||||
|         const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); | ||||
|         double z_offset = volume->get_sla_shift_z(); | ||||
| 
 | ||||
|         // bounding box created from the rectangle corners - will take care of order of the corners
 | ||||
|         BoundingBox rectangle(Points{Point(m_selection_rectangle_start_corner.cast<int>()), Point(m_selection_rectangle_end_corner.cast<int>())}); | ||||
| 
 | ||||
|         for (std::pair<sla::SupportPoint, bool>& point_and_selection : m_editing_mode_cache) { | ||||
|             const sla::SupportPoint& support_point = point_and_selection.first; | ||||
|             Vec3f pos = instance_matrix.cast<float>() * support_point.pos; | ||||
|             pos(2) += z_offset; | ||||
|             GLdouble out_x, out_y, out_z; | ||||
|             ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z); | ||||
|             out_y = m_canvas_height - out_y; | ||||
| 
 | ||||
|             if (rectangle.contains(Point(out_x, out_y))) | ||||
|                 point_and_selection.second = true; | ||||
|         } | ||||
|         m_selection_rectangle_active = false; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     if (action == SLAGizmoEventType::Delete) { | ||||
|         // delete key pressed
 | ||||
|         delete_selected_points(); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     if (action == SLAGizmoEventType::SelectAll) { | ||||
|         for (auto& point_and_selection : m_editing_mode_cache) | ||||
|             point_and_selection.second = true; | ||||
|             return true; | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSlaSupports::delete_selected_points() | ||||
| { | ||||
|     if (!m_editing_mode) | ||||
|         return; | ||||
| 
 | ||||
|     int instance_id = m_parent.get_selection().get_instance_idx(); | ||||
|     if (m_old_instance_id != instance_id) | ||||
|     { | ||||
|         bool something_selected = (m_old_instance_id != -1); | ||||
|         m_old_instance_id = instance_id; | ||||
|         if (something_selected) | ||||
|             return; | ||||
|     for (unsigned int idx=0; idx<m_editing_mode_cache.size(); ++idx) { | ||||
|         if (m_editing_mode_cache[idx].second && (!m_editing_mode_cache[idx].first.is_new_island || !m_lock_unique_islands)) | ||||
|             m_editing_mode_cache.erase(m_editing_mode_cache.begin() + (idx--)); | ||||
|             // This should trigger the support generation
 | ||||
|             // wxGetApp().plater()->reslice();
 | ||||
|     } | ||||
|     if (instance_id == -1) | ||||
|         return; | ||||
| 
 | ||||
|     Vec3f new_pos; | ||||
|     try { | ||||
|         new_pos = unproject_on_mesh(mouse_position); // this can throw - we don't want to create a new point in that case
 | ||||
|     } | ||||
|     catch (...) { return; } | ||||
| 
 | ||||
|     m_editing_mode_cache.emplace_back(new_pos, m_new_point_head_diameter, false); | ||||
| 
 | ||||
|     // This should trigger the support generation
 | ||||
|     // wxGetApp().plater()->reslice();
 | ||||
| 
 | ||||
|     m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSlaSupports::delete_current_point(bool delete_all) | ||||
| { | ||||
|     if (!m_editing_mode && !delete_all) | ||||
|         return; | ||||
| 
 | ||||
|     if (delete_all) { | ||||
|         m_editing_mode_cache.clear(); | ||||
| 
 | ||||
|         // This should trigger the support generation
 | ||||
|         // wxGetApp().plater()->reslice();
 | ||||
|     } | ||||
|     else | ||||
|         if (m_hover_id != -1) { | ||||
|             if (!m_editing_mode_cache[m_hover_id].is_new_island || !m_lock_unique_islands) { | ||||
|                 m_editing_mode_cache.erase(m_editing_mode_cache.begin() + m_hover_id); | ||||
|                 m_hover_id = -1; | ||||
| 
 | ||||
|                 // This should trigger the support generation
 | ||||
|                 // wxGetApp().plater()->reslice();
 | ||||
|             } | ||||
|         } | ||||
|     //m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
 | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSlaSupports::on_update(const UpdateData& data, const GLCanvas3D::Selection& selection) | ||||
| { | ||||
|     if (m_editing_mode && m_hover_id != -1 && data.mouse_pos && (!m_editing_mode_cache[m_hover_id].is_new_island || !m_lock_unique_islands)) { | ||||
|     if (m_editing_mode && m_hover_id != -1 && data.mouse_pos && (!m_editing_mode_cache[m_hover_id].first.is_new_island || !m_lock_unique_islands)) { | ||||
|         Vec3f new_pos; | ||||
|         try { | ||||
|             new_pos = unproject_on_mesh(Vec2d((*data.mouse_pos)(0), (*data.mouse_pos)(1))); | ||||
|         } | ||||
|         catch (...) { return; } | ||||
|         m_editing_mode_cache[m_hover_id].pos = new_pos; | ||||
|         m_editing_mode_cache[m_hover_id].is_new_island = false; | ||||
|         m_editing_mode_cache[m_hover_id].first.pos = new_pos; | ||||
|         m_editing_mode_cache[m_hover_id].first.is_new_island = false; | ||||
|         // Do not update immediately, wait until the mouse is released.
 | ||||
|         // m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
 | ||||
|     } | ||||
|  | @ -2097,29 +2215,13 @@ RENDER_AGAIN: | |||
| 
 | ||||
|     ImGui::PushItemWidth(100.0f); | ||||
| 
 | ||||
|     /*bool force_refresh = m_editing_mode;
 | ||||
|     if (m_imgui->radio_button(_(L("Automatic")), !m_editing_mode)) | ||||
|         m_editing_mode = false; | ||||
|     ImGui::SameLine(); | ||||
|     if (m_imgui->radio_button(_(L("Manual")), m_editing_mode)) | ||||
|         m_editing_mode = true; | ||||
|     force_refresh = force_refresh != m_editing_mode; | ||||
| 
 | ||||
|     if (force_refresh) { // mode has just changed!
 | ||||
|         if (m_editing_mode) | ||||
|             m_editing_mode_cache = m_model_object->sla_support_points; | ||||
|         else | ||||
|             m_model_object->sla_support_points = m_editing_mode_cache; | ||||
|     } | ||||
|     */ | ||||
| 
 | ||||
|     bool force_refresh = false; | ||||
|     bool remove_all_points = false; | ||||
|     bool remove_selected = false; | ||||
|     bool old_editing_state = m_editing_mode; | ||||
| 
 | ||||
|     if (m_editing_mode) { | ||||
|         m_imgui->text(_(L("Left mouse click - add point"))); | ||||
|         m_imgui->text(_(L("Right mouse click - remove point"))); | ||||
|         m_imgui->text(_(L("Shift + Left (+ drag) - select point(s)"))); | ||||
|         m_imgui->text(" ");  // vertical gap
 | ||||
| 
 | ||||
|         std::vector<wxString> options = {"0.2", "0.4", "0.6", "0.8", "1.0"}; | ||||
|  | @ -2127,28 +2229,38 @@ RENDER_AGAIN: | |||
|         ss << std::setprecision(1) << m_new_point_head_diameter; | ||||
|         wxString str = ss.str(); | ||||
|         m_imgui->combo(_(L("Head diameter")), options, str); | ||||
|         force_refresh |= std::abs(atof(str) - m_new_point_head_diameter) > 0.001; | ||||
|         m_new_point_head_diameter = atof(str); | ||||
|         float current_number = atof(str); | ||||
|         if (std::abs(current_number - m_new_point_head_diameter) > 0.001) { | ||||
|             force_refresh = true; | ||||
|             m_new_point_head_diameter = current_number; | ||||
|             for (auto& point_and_selection : m_editing_mode_cache) | ||||
|                 if (point_and_selection.second) | ||||
|                     point_and_selection.first.head_front_radius = current_number / 2.f; | ||||
|         } | ||||
| 
 | ||||
|         bool changed = m_lock_unique_islands; | ||||
|         m_imgui->checkbox(_(L("Lock supports under new islands")), m_lock_unique_islands); | ||||
|         force_refresh |= changed != m_lock_unique_islands; | ||||
| 
 | ||||
|         remove_all_points = m_imgui->button(_(L("Remove all points")) + (m_model_object == nullptr ? "" : " (" + std::to_string(m_editing_mode_cache.size())+")")); | ||||
|         remove_selected = m_imgui->button(_(L("Remove selected points"))); | ||||
| 
 | ||||
|         m_imgui->text(" "); // vertical gap
 | ||||
| 
 | ||||
|         bool apply_changes = m_imgui->button(_(L("Apply changes"))); | ||||
|         if (apply_changes) { | ||||
|             m_model_object->sla_support_points = m_editing_mode_cache; | ||||
|             m_model_object->sla_support_points.clear(); | ||||
|             for (const std::pair<sla::SupportPoint, bool>& point_and_selection : m_editing_mode_cache) | ||||
|                 m_model_object->sla_support_points.push_back(point_and_selection.first); | ||||
|             m_editing_mode = false; | ||||
|             force_refresh = true; | ||||
|             m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); | ||||
|         } | ||||
|         ImGui::SameLine(); | ||||
|         bool discard_changes = m_imgui->button(_(L("Cancel"))); | ||||
|         bool discard_changes = m_imgui->button(_(L("Discard changes"))); | ||||
|         if (discard_changes) { | ||||
|             m_editing_mode_cache = m_model_object->sla_support_points; | ||||
|             m_editing_mode_cache.clear(); | ||||
|             for (const sla::SupportPoint& point : m_model_object->sla_support_points) | ||||
|                 m_editing_mode_cache.push_back(std::make_pair(point, false)); | ||||
|             m_editing_mode = false; | ||||
|             force_refresh = true; | ||||
|         } | ||||
|  | @ -2161,17 +2273,60 @@ RENDER_AGAIN: | |||
| 
 | ||||
|         m_imgui->text(""); | ||||
| 
 | ||||
|         bool generate =m_imgui->button(_(L("Auto-generate points"))); | ||||
|         force_refresh |= generate; | ||||
|         bool generate = m_imgui->button(_(L("Auto-generate points"))); | ||||
| 
 | ||||
|         if (generate) { | ||||
|             m_model_object->sla_support_points.clear(); | ||||
|             m_editing_mode_cache.clear(); | ||||
|             wxGetApp().plater()->reslice(); | ||||
| #if SLAGIZMO_IMGUI_MODAL | ||||
|             ImGui::OpenPopup(_(L("Warning"))); | ||||
|             m_show_modal = true; | ||||
|             force_refresh = true; | ||||
| #else | ||||
|             wxMessageDialog dlg(GUI::wxGetApp().plater(), _(L( | ||||
|                         "Autogeneration will erase all currently assigned points.\n\n" | ||||
|                         "Are you sure you want to do it?\n" | ||||
|                         )), _(L("Warning")), wxICON_WARNING | wxYES | wxNO); | ||||
|                     if (dlg.ShowModal() == wxID_YES) { | ||||
|                         m_model_object->sla_support_points.clear(); | ||||
|                         m_editing_mode_cache.clear(); | ||||
|                         wxGetApp().plater()->reslice(); | ||||
|                     } | ||||
| #endif | ||||
|         } | ||||
| #if SLAGIZMO_IMGUI_MODAL | ||||
|         if (m_show_modal) { | ||||
|             if (ImGui::BeginPopupModal(_(L("Warning")), &m_show_modal/*, ImGuiWindowFlags_NoDecoration*/)) | ||||
|             { | ||||
|                 m_imgui->text(_(L("Autogeneration will erase all currently assigned points."))); | ||||
|                 m_imgui->text(""); | ||||
|                 m_imgui->text(_(L("Are you sure you want to do it?"))); | ||||
| 
 | ||||
|                 if (m_imgui->button(_(L("Continue")))) | ||||
|                 { | ||||
|                     ImGui::CloseCurrentPopup(); | ||||
|                     m_show_modal = false; | ||||
| 
 | ||||
|                     m_model_object->sla_support_points.clear(); | ||||
|                     m_editing_mode_cache.clear(); | ||||
|                     wxGetApp().plater()->reslice(); | ||||
|                 } | ||||
|                 ImGui::SameLine(); | ||||
|                 if (m_imgui->button(_(L("Cancel")))) { | ||||
|                     ImGui::CloseCurrentPopup(); | ||||
|                     m_show_modal = false; | ||||
|                 } | ||||
|             ImGui::EndPopup(); | ||||
|             } | ||||
| 
 | ||||
|             if (!m_show_modal) | ||||
|                 force_refresh = true; | ||||
|         } | ||||
| #endif | ||||
|         ImGui::SameLine(); | ||||
|         bool editing_clicked = m_imgui->button("Editing"); | ||||
|         if (editing_clicked) { | ||||
|             m_editing_mode_cache = m_model_object->sla_support_points; | ||||
|             m_editing_mode_cache.clear(); | ||||
|             for (const sla::SupportPoint& point : m_model_object->sla_support_points) | ||||
|                 m_editing_mode_cache.push_back(std::make_pair(point, false)); | ||||
|             m_editing_mode = true; | ||||
|         } | ||||
|     } | ||||
|  | @ -2184,10 +2339,10 @@ RENDER_AGAIN: | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     if (remove_all_points) { | ||||
|     if (remove_selected) { | ||||
|         force_refresh = false; | ||||
|         m_parent.reload_scene(true); | ||||
|         delete_current_point(true); | ||||
|         delete_selected_points(); | ||||
|         if (first_run) { | ||||
|             first_run = false; | ||||
|             goto RENDER_AGAIN; | ||||
|  | @ -2228,9 +2383,22 @@ void GLGizmoSlaSupports::on_set_state() | |||
|     if (m_state == Off) { | ||||
|         m_parent.toggle_model_objects_visibility(true); | ||||
|         m_editing_mode = false; | ||||
| #if SLAGIZMO_IMGUI_MODAL | ||||
|         if (m_show_modal) { | ||||
|             m_show_modal = false; | ||||
|             on_render_input_window(0,0,m_parent.get_selection()); // this is necessary to allow ImGui to terminate the modal dialog correctly
 | ||||
|         } | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSlaSupports::on_start_dragging(const GLCanvas3D::Selection& selection) | ||||
| { | ||||
|     if (m_hover_id != -1) | ||||
|         for (unsigned int i=0;i<m_editing_mode_cache.size();++i) | ||||
|             m_editing_mode_cache[i].second = ((int)i == m_hover_id); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // GLGizmoCut
 | ||||
|  |  | |||
|  | @ -437,6 +437,9 @@ protected: | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #define SLAGIZMO_IMGUI_MODAL 1 | ||||
| class GLGizmoSlaSupports : public GLGizmoBase | ||||
| { | ||||
| private: | ||||
|  | @ -464,8 +467,8 @@ public: | |||
|     explicit GLGizmoSlaSupports(GLCanvas3D& parent); | ||||
|     virtual ~GLGizmoSlaSupports(); | ||||
|     void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection); | ||||
|     void clicked_on_object(const Vec2d& mouse_position); | ||||
|     void delete_current_point(bool delete_all); | ||||
|     bool mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down); | ||||
|     void delete_selected_points(); | ||||
| 
 | ||||
| private: | ||||
|     bool on_init(); | ||||
|  | @ -473,6 +476,7 @@ private: | |||
|     virtual void on_render(const GLCanvas3D::Selection& selection) const; | ||||
|     virtual void on_render_for_picking(const GLCanvas3D::Selection& selection) const; | ||||
| 
 | ||||
|     void render_selection_rectangle() const; | ||||
|     void render_points(const GLCanvas3D::Selection& selection, bool picking = false) const; | ||||
|     bool is_mesh_update_necessary() const; | ||||
|     void update_mesh(); | ||||
|  | @ -486,10 +490,21 @@ private: | |||
|     bool m_lock_unique_islands = false; | ||||
|     bool m_editing_mode = false; | ||||
|     float m_new_point_head_diameter = 0.4f; | ||||
|     std::vector<sla::SupportPoint> m_editing_mode_cache; | ||||
|     std::vector<std::pair<sla::SupportPoint, bool>> m_editing_mode_cache; // a support point and whether it is currently selected
 | ||||
| 
 | ||||
|     bool m_selection_rectangle_active = false; | ||||
|     Vec2d m_selection_rectangle_start_corner; | ||||
|     Vec2d m_selection_rectangle_end_corner; | ||||
|     bool m_ignore_up_event = false; | ||||
| #if SLAGIZMO_IMGUI_MODAL | ||||
|     bool m_show_modal = false; | ||||
| #endif | ||||
|     int m_canvas_width; | ||||
|     int m_canvas_height; | ||||
| 
 | ||||
| protected: | ||||
|     void on_set_state() override; | ||||
|     void on_start_dragging(const GLCanvas3D::Selection& selection) override; | ||||
| 
 | ||||
| #if ENABLE_IMGUI | ||||
|     virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) override; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv