mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	SLA gizmo now respects the clipping plane when rendering points and raycasting mouse onto mesh
This commit is contained in:
		
							parent
							
								
									fd1f9d65fb
								
							
						
					
					
						commit
						bc9164e40c
					
				
					 4 changed files with 74 additions and 27 deletions
				
			
		|  | @ -2582,27 +2582,7 @@ void GLCanvas3D::render() | |||
|     if (early_bed_render) | ||||
|         _render_bed(theta); | ||||
| 
 | ||||
| ////////////////////////
 | ||||
|     //Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> stashed_projection_matrix;
 | ||||
|     //::glGetDoublev(GL_PROJECTION_MATRIX, stashed_projection_matrix.data());
 | ||||
|     const Size& cnv_size = get_canvas_size(); | ||||
|     if (m_gizmos.get_current_type() == Gizmos::SlaSupports) { | ||||
|         std::pair<float, float> clipping_limits = m_gizmos.get_sla_clipping_plane(); | ||||
|         set_ortho_projection((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height(), clipping_limits.first, clipping_limits.second); | ||||
|     } | ||||
| 
 | ||||
| ////////////////////
 | ||||
|     _render_objects(); | ||||
| //////////////////////////////////
 | ||||
|     if (m_gizmos.get_current_type() == Gizmos::SlaSupports) { | ||||
|         //::glMatrixMode(GL_PROJECTION);
 | ||||
|         //::glLoadIdentity();
 | ||||
|         //::glMultMatrixd(stashed_projection_matrix.data());
 | ||||
|         //::glMatrixMode(GL_MODELVIEW);
 | ||||
|         _resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); | ||||
|     } | ||||
| //////////////////////////////////
 | ||||
| 
 | ||||
|     _render_sla_slices(); | ||||
|     _render_selection(); | ||||
| 
 | ||||
|  | @ -4720,6 +4700,28 @@ void GLCanvas3D::set_ortho_projection(float w, float h, float near, float far) c | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| void GLCanvas3D::set_sla_clipping(bool enable) const | ||||
| { | ||||
|     if (m_gizmos.get_current_type() != Gizmos::SlaSupports) | ||||
|         return; | ||||
| 
 | ||||
|     if (enable) { | ||||
|         ::glMatrixMode(GL_PROJECTION); | ||||
|         ::glPushMatrix(); | ||||
|         ::glMatrixMode(GL_MODELVIEW); | ||||
|         const Size& cnv_size = get_canvas_size(); | ||||
|         std::pair<float, float> clipping_limits = m_gizmos.get_sla_clipping_plane(); | ||||
|         set_ortho_projection((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height(), clipping_limits.first, clipping_limits.second); | ||||
|     } | ||||
|     else { | ||||
|         ::glMatrixMode(GL_PROJECTION); | ||||
|         ::glPopMatrix(); | ||||
|         ::glMatrixMode(GL_MODELVIEW); | ||||
|         ::glClear(GL_DEPTH_BUFFER_BIT); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void GLCanvas3D::_render_objects() const | ||||
| { | ||||
|     if (m_volumes.empty()) | ||||
|  | @ -4728,6 +4730,8 @@ void GLCanvas3D::_render_objects() const | |||
|     ::glEnable(GL_LIGHTING); | ||||
|     ::glEnable(GL_DEPTH_TEST); | ||||
| 
 | ||||
|     set_sla_clipping(true); | ||||
| 
 | ||||
|     if (m_use_VBOs) | ||||
|     { | ||||
|         if (m_picking_enabled) | ||||
|  | @ -4789,6 +4793,8 @@ void GLCanvas3D::_render_objects() const | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     set_sla_clipping(false); | ||||
| 
 | ||||
|     ::glDisable(GL_LIGHTING); | ||||
| } | ||||
| 
 | ||||
|  | @ -4831,6 +4837,8 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const | |||
|     if (!fake_colors) | ||||
|         ::glEnable(GL_LIGHTING); | ||||
| 
 | ||||
|     set_sla_clipping(true); | ||||
| 
 | ||||
|     // do not cull backfaces to show broken geometry, if any
 | ||||
|     ::glDisable(GL_CULL_FACE); | ||||
| 
 | ||||
|  | @ -4869,6 +4877,8 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const | |||
| 
 | ||||
|     ::glEnable(GL_CULL_FACE); | ||||
| 
 | ||||
|     set_sla_clipping(false); | ||||
| 
 | ||||
|     if (!fake_colors) | ||||
|         ::glDisable(GL_LIGHTING); | ||||
| } | ||||
|  |  | |||
|  | @ -778,6 +778,9 @@ private: | |||
|     // Sets current projection matrix to ortho, accounting for current camera zoom.
 | ||||
|     void set_ortho_projection(float w, float h, float near, float far) const; | ||||
| 
 | ||||
|     // Set/unset near clipping plane according to SLA gizmo requirements.
 | ||||
|     void set_sla_clipping(bool enable) const; | ||||
| 
 | ||||
|     void _start_timer(); | ||||
|     void _stop_timer(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -157,6 +157,11 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) | |||
|     const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); | ||||
|     const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix(); | ||||
| 
 | ||||
|     // we'll recover current look direction from the modelview matrix (in world coords):
 | ||||
|     Eigen::Matrix<double, 4, 4, Eigen::DontAlign> modelview_matrix; | ||||
|     ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()); | ||||
|     Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]); | ||||
| 
 | ||||
|     ::glPushMatrix(); | ||||
|     ::glTranslated(0.0, 0.0, z_shift); | ||||
|     ::glMultMatrixd(instance_matrix.data()); | ||||
|  | @ -167,6 +172,9 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) | |||
|         const sla::SupportPoint& support_point = m_editing_mode_cache[i].support_point; | ||||
|         const bool& point_selected = m_editing_mode_cache[i].selected; | ||||
| 
 | ||||
|         if (is_point_clipped(support_point.pos.cast<double>(), direction_to_camera, z_shift)) | ||||
|             continue; | ||||
| 
 | ||||
|         // First decide about the color of the point.
 | ||||
|         if (picking) { | ||||
|             std::array<float, 3> color = picking_color_component(i); | ||||
|  | @ -285,6 +293,8 @@ void GLGizmoSlaSupports::update_mesh() | |||
|     m_AABB.init(m_V, m_F); | ||||
| } | ||||
| 
 | ||||
| // Unprojects the mouse position on the mesh and return the hit point and normal of the facet.
 | ||||
| // The function throws if no intersection if found.
 | ||||
| std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) | ||||
| { | ||||
|     // if the gizmo doesn't have the V, F structures for igl, calculate them first:
 | ||||
|  | @ -303,12 +313,15 @@ std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse | |||
|     ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2)); | ||||
|     ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2)); | ||||
| 
 | ||||
|     igl::Hit hit; | ||||
|     std::vector<igl::Hit> hits; | ||||
| 
 | ||||
|     const 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(); | ||||
| 
 | ||||
|     // we'll recover current look direction from the modelview matrix (in world coords):
 | ||||
|     Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]); | ||||
| 
 | ||||
|     point1(2) -= z_offset; | ||||
| 	point2(2) -= z_offset; | ||||
| 
 | ||||
|  | @ -317,17 +330,37 @@ std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse | |||
|     point1 = inv * point1; | ||||
|     point2 = inv * point2; | ||||
| 
 | ||||
|     if (!m_AABB.intersect_ray(m_V, m_F, point1.cast<float>(), (point2-point1).cast<float>(), hit)) | ||||
|     if (!m_AABB.intersect_ray(m_V, m_F, point1.cast<float>(), (point2-point1).cast<float>(), hits)) | ||||
|         throw std::invalid_argument("unproject_on_mesh(): No intersection found."); | ||||
| 
 | ||||
|     int fid = hit.id;   // facet id
 | ||||
|     Vec3f bc(1-hit.u-hit.v, hit.u, hit.v); // barycentric coordinates of the hit
 | ||||
|     Vec3f a = (m_V.row(m_F(fid, 1)) - m_V.row(m_F(fid, 0))); | ||||
|     Vec3f b = (m_V.row(m_F(fid, 2)) - m_V.row(m_F(fid, 0))); | ||||
|     std::sort(hits.begin(), hits.end(), [](const igl::Hit& a, const igl::Hit& b) { return a.t < b.t; }); | ||||
| 
 | ||||
|     // Now let's iterate through the points and find the first that is not clipped:
 | ||||
|     unsigned int i=0; | ||||
|     Vec3f bc; | ||||
|     Vec3f a; | ||||
|     Vec3f b; | ||||
|     Vec3f result; | ||||
|     for (i=0; i<hits.size(); ++i) { | ||||
|         igl::Hit& hit = hits[i]; | ||||
|         int fid = hit.id;   // facet id
 | ||||
|         bc = Vec3f(1-hit.u-hit.v, hit.u, hit.v); // barycentric coordinates of the hit
 | ||||
|         a = (m_V.row(m_F(fid, 1)) - m_V.row(m_F(fid, 0))); | ||||
|         b = (m_V.row(m_F(fid, 2)) - m_V.row(m_F(fid, 0))); | ||||
|         result = 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)); | ||||
|         if (m_clipping_plane_distance == 0.f || !is_point_clipped(result.cast<double>(), direction_to_camera, z_offset)) | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     if (i==hits.size() || (hits.size()-i) % 2 != 0) { | ||||
|         // All hits are either clipped, or there is an odd number of unclipped
 | ||||
|         // hits - meaning the nearest must be from inside the mesh.
 | ||||
|         throw std::invalid_argument("unproject_on_mesh(): No intersection found."); | ||||
|     } | ||||
| 
 | ||||
|     // Calculate and return both the point and the facet normal.
 | ||||
|     return std::make_pair( | ||||
|             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)), | ||||
|             result, | ||||
|             a.cross(b) | ||||
|         ); | ||||
| } | ||||
|  |  | |||
|  | @ -86,6 +86,7 @@ private: | |||
|     int m_canvas_height; | ||||
| 
 | ||||
|     std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const; | ||||
|     bool is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera, float z_shift) const; | ||||
| 
 | ||||
|     // Methods that do the model_object and editing cache synchronization,
 | ||||
|     // editing mode selection, etc:
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukas Matena
						Lukas Matena