mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	First steps on SLA clipping plane
This commit is contained in:
		
							parent
							
								
									2487bb8794
								
							
						
					
					
						commit
						fd1f9d65fb
					
				
					 4 changed files with 150 additions and 20 deletions
				
			
		|  | @ -1317,6 +1317,22 @@ bool GLCanvas3D::Gizmos::gizmo_event(SLAGizmoEventType action, const Vec2d& mous | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| std::pair<float, float> GLCanvas3D::Gizmos::get_sla_clipping_plane() const | ||||
| { | ||||
|     if (!m_enabled) | ||||
|         return std::make_pair(0.f, 0.f); | ||||
| 
 | ||||
|     GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); | ||||
|     if (it != m_gizmos.end()) | ||||
|         return reinterpret_cast<GLGizmoSlaSupports*>(it->second)->get_sla_clipping_plane(); | ||||
| 
 | ||||
|     return std::make_pair(0.f, 0.f);; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| void GLCanvas3D::Gizmos::render_current_gizmo(const Selection& selection) const | ||||
| { | ||||
|     if (!m_enabled) | ||||
|  | @ -2566,7 +2582,27 @@ 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(); | ||||
| 
 | ||||
|  | @ -4416,29 +4452,13 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) | |||
|     _set_current(); | ||||
|     ::glViewport(0, 0, w, h); | ||||
| 
 | ||||
|     ::glMatrixMode(GL_PROJECTION); | ||||
|     ::glLoadIdentity(); | ||||
| 
 | ||||
|     const BoundingBoxf3& bbox = _max_bounding_box(); | ||||
| 
 | ||||
|     switch (m_camera.type) | ||||
|     { | ||||
|     case Camera::Ortho: | ||||
|     { | ||||
|         float w2 = w; | ||||
|         float h2 = h; | ||||
|         float two_zoom = 2.0f * get_camera_zoom(); | ||||
|         if (two_zoom != 0.0f) | ||||
|         { | ||||
|             float inv_two_zoom = 1.0f / two_zoom; | ||||
|             w2 *= inv_two_zoom; | ||||
|             h2 *= inv_two_zoom; | ||||
|         } | ||||
| 
 | ||||
|         // FIXME: calculate a tighter value for depth will improve z-fighting
 | ||||
|         float depth = 5.0f * (float)bbox.max_size(); | ||||
|         ::glOrtho(-w2, w2, -h2, h2, -depth, depth); | ||||
| 
 | ||||
|         float depth = 5.0f * (float)(_max_bounding_box().max_size()); | ||||
|         set_ortho_projection(w, h, -depth, depth); | ||||
|         break; | ||||
|     } | ||||
| //    case Camera::Perspective:
 | ||||
|  | @ -4470,8 +4490,6 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) | |||
|     } | ||||
|     } | ||||
| 
 | ||||
|     ::glMatrixMode(GL_MODELVIEW); | ||||
| 
 | ||||
|     m_dirty = false; | ||||
| } | ||||
| 
 | ||||
|  | @ -4685,6 +4703,23 @@ void GLCanvas3D::_render_axes() const | |||
|     m_bed.render_axes(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void GLCanvas3D::set_ortho_projection(float w, float h, float near, float far) const | ||||
| { | ||||
|     float two_zoom = 2.0f * get_camera_zoom(); | ||||
|     if (two_zoom != 0.0f) | ||||
|     { | ||||
|         float inv_two_zoom = 1.0f / two_zoom; | ||||
|         w *= inv_two_zoom; | ||||
|         h *= inv_two_zoom; | ||||
|     } | ||||
|     ::glMatrixMode(GL_PROJECTION); | ||||
|     ::glLoadIdentity(); | ||||
|     ::glOrtho(-w, w, -h, h, near, far); | ||||
|     ::glMatrixMode(GL_MODELVIEW); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void GLCanvas3D::_render_objects() const | ||||
| { | ||||
|     if (m_volumes.empty()) | ||||
|  |  | |||
|  | @ -448,6 +448,7 @@ private: | |||
| 
 | ||||
|         void set_sla_support_data(ModelObject* model_object, const Selection& selection); | ||||
|         bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false); | ||||
|         std::pair<float, float> get_sla_clipping_plane() const; | ||||
| 
 | ||||
|         void render_current_gizmo(const Selection& selection) const; | ||||
|         void render_current_gizmo_for_picking_pass(const Selection& selection) const; | ||||
|  | @ -774,6 +775,9 @@ private: | |||
|     // Returns the view ray line, in world coordinate, at the given mouse position.
 | ||||
|     Linef3 mouse_ray(const Point& mouse_pos); | ||||
| 
 | ||||
|     // Sets current projection matrix to ortho, accounting for current camera zoom.
 | ||||
|     void set_ortho_projection(float w, float h, float near, float far) const; | ||||
| 
 | ||||
|     void _start_timer(); | ||||
|     void _stop_timer(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -56,6 +56,10 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S | |||
| 
 | ||||
|     if (model_object && selection.is_from_single_instance()) | ||||
|     { | ||||
|         // Cache the bb - it's needed for dealing with the clipping plane quite often
 | ||||
|         // It could be done inside update_mesh but one has to account for scaling of the instance.
 | ||||
|         m_active_instance_bb = m_model_object->instance_bounding_box(m_active_instance); | ||||
| 
 | ||||
|         if (is_mesh_update_necessary()) { | ||||
|             update_mesh(); | ||||
|             editing_mode_reload_cache(); | ||||
|  | @ -232,6 +236,21 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) | |||
|     ::glPopMatrix(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| bool GLGizmoSlaSupports::is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera, float z_shift) const | ||||
| { | ||||
|     if (m_clipping_plane_distance == 0.f) | ||||
|         return false; | ||||
| 
 | ||||
|     Vec3d transformed_point = m_model_object->instances.front()->get_transformation().get_matrix() * point; | ||||
|     transformed_point(2) += z_shift; | ||||
|     return direction_to_camera.dot(m_active_instance_bb.center()) + m_active_instance_bb.radius() | ||||
|             - m_clipping_plane_distance * 2*m_active_instance_bb.radius() < direction_to_camera.dot(transformed_point); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| bool GLGizmoSlaSupports::is_mesh_update_necessary() const | ||||
| { | ||||
|     return ((m_state == On) && (m_model_object != nullptr) && !m_model_object->instances.empty()) | ||||
|  | @ -559,6 +578,69 @@ void GLGizmoSlaSupports::update_cache_entry_normal(unsigned int i) const | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| std::pair<float, float> GLGizmoSlaSupports::get_sla_clipping_plane() const | ||||
| { | ||||
|     if (!m_model_object) | ||||
|         return std::make_pair(0.f, 0.f);; | ||||
| 
 | ||||
|     Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> modelview_matrix; | ||||
|     ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()); | ||||
| 
 | ||||
|     // clipping space origin transformed to world coords:
 | ||||
|     Vec3d clipping_origin = (modelview_matrix.inverse() * Eigen::Matrix<GLdouble, 4, 1, Eigen::DontAlign>{0, 0, 0, 1}).block<3,1>(0,0); | ||||
| 
 | ||||
|     // 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]); | ||||
|     float dist = direction_to_camera.dot(clipping_origin) - direction_to_camera.dot(m_active_instance_bb.center()); | ||||
| 
 | ||||
|     return std::make_pair((dist - m_active_instance_bb.radius()) + m_clipping_plane_distance * 2*m_active_instance_bb.radius(), dist + 5.f*m_active_instance_bb.radius()); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
| void GLGizmoSlaSupports::find_intersections(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<IntersectionLine>& idxs) const | ||||
| { | ||||
|     if (aabb->is_leaf()) { // this is a facet
 | ||||
|         // corner.dot(normal) - offset
 | ||||
|         unsigned int facet_idx = aabb->m_primitive; | ||||
| 
 | ||||
|         Vec3f a = m_V.row(m_F(facet_idx, 0)); | ||||
|         Vec3f b = m_V.row(m_F(facet_idx, 1)); | ||||
|         Vec3f c = m_V.row(m_F(facet_idx, 2)); | ||||
|     } | ||||
|     else { // not a leaf
 | ||||
|     using CornerType = Eigen::AlignedBox<float, 3>::CornerType; | ||||
|         bool sign = std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(0)))); | ||||
|         for (unsigned int i=1; i<8; ++i) | ||||
|             if (std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(i)))) != sign) { | ||||
|                 find_intersections(aabb->m_left, normal, offset, idxs); | ||||
|                 find_intersections(aabb->m_right, normal, offset, idxs); | ||||
|             } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLGizmoSlaSupports::make_line_segments() const | ||||
| { | ||||
|     TriangleMeshSlicer tms(&m_model_object->volumes.front()->mesh); | ||||
|     Vec3f normal(0.f, 1.f, 1.f); | ||||
|     double d = 0.; | ||||
| 
 | ||||
|     std::vector<IntersectionLine> lines; | ||||
|     find_intersections(&m_AABB, normal, d, lines); | ||||
|     ExPolygons expolys; | ||||
|     tms.make_expolygons_simple(lines, &expolys); | ||||
| 
 | ||||
|     SVG svg("slice_loops.svg", get_extents(expolys)); | ||||
|     svg.draw(expolys); | ||||
|     //for (const IntersectionLine &l : lines[i])
 | ||||
|     //    svg.draw(l, "red", 0);
 | ||||
|     //svg.draw_outline(expolygons, "black", "blue", 0);
 | ||||
|     svg.Close(); | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| 
 | ||||
| void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) | ||||
| { | ||||
|     if (!m_model_object) | ||||
|  | @ -676,6 +758,13 @@ RENDER_AGAIN: | |||
|                      (m_model_object->sla_points_status == sla::PointsStatus::Generating ? "Generation in progress..." : "UNKNOWN STATUS")))); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // Following is rendered in both editing and non-editing mode:
 | ||||
|     m_imgui->text("Clipping of view: "); | ||||
|     ImGui::SameLine(); | ||||
|     ImGui::PushItemWidth(150.0f); | ||||
|     bool value_changed = ImGui::SliderFloat("  ", &m_clipping_plane_distance, 0.f, 1.f, "%.2f"); | ||||
|      | ||||
|     m_imgui->end(); | ||||
| 
 | ||||
|     if (m_editing_mode != m_old_editing_state) { // user toggled between editing/non-editing mode
 | ||||
|  | @ -761,6 +850,7 @@ void GLGizmoSlaSupports::on_set_state() | |||
|         m_parent.toggle_model_objects_visibility(true); | ||||
|         m_editing_mode = false; // so it is not active next time the gizmo opens
 | ||||
|         m_editing_mode_cache.clear(); | ||||
|         m_clipping_plane_distance = 0.f; | ||||
|     } | ||||
|     m_old_state = m_state; | ||||
| } | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ private: | |||
|     ModelObject* m_model_object = nullptr; | ||||
|     ModelObject* m_old_model_object = nullptr; | ||||
|     int m_active_instance = -1; | ||||
|     BoundingBoxf3 m_active_instance_bb; // to cache the bb
 | ||||
|     std::pair<Vec3f, Vec3f> unproject_on_mesh(const Vec2d& mouse_pos); | ||||
| 
 | ||||
|     const float RenderPointScale = 1.f; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukas Matena
						Lukas Matena