mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Fixed out-of-bouds access in RammingChart.cpp in case the ramming was turned off
This commit is contained in:
		
							parent
							
								
									e9d629f248
								
							
						
					
					
						commit
						7185125f9c
					
				
					 1 changed files with 81 additions and 82 deletions
				
			
		|  | @ -141,6 +141,9 @@ void Chart::mouse_double_clicked(wxMouseEvent& event) { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void Chart::recalculate_line() { | void Chart::recalculate_line() { | ||||||
|  |     m_line_to_draw.clear(); | ||||||
|  |     m_total_volume = 0.f; | ||||||
|  | 
 | ||||||
|     std::vector<wxPoint> points; |     std::vector<wxPoint> points; | ||||||
|     for (auto& but : m_buttons) { |     for (auto& but : m_buttons) { | ||||||
|         points.push_back(wxPoint(math_to_screen(but.get_pos()))); |         points.push_back(wxPoint(math_to_screen(but.get_pos()))); | ||||||
|  | @ -150,92 +153,88 @@ void Chart::recalculate_line() { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; }); | 
 | ||||||
|      |     // The calculation wouldn't work in case the ramming is to be turned off completely.
 | ||||||
|     m_line_to_draw.clear(); |     if (points.size()>1) { | ||||||
|     m_total_volume = 0.f; |         std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; }); | ||||||
|     | 
 | ||||||
|     |         // Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods
 | ||||||
|     // Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods
 |         const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point
 | ||||||
|     const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point
 |                                                      // false - second ---- || -------
 | ||||||
|                                                  // false - second ---- || -------
 |         const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points
 | ||||||
|     const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points
 |         std::vector<float> diag(N+1); | ||||||
|     std::vector<float> diag(N+1); |         std::vector<float> mu(N+1); | ||||||
|     std::vector<float> mu(N+1); |         std::vector<float> lambda(N+1); | ||||||
|     std::vector<float> lambda(N+1); |         std::vector<float> h(N+1); | ||||||
|     std::vector<float> h(N+1); |         std::vector<float> rhs(N+1); | ||||||
|     std::vector<float> rhs(N+1); |  | ||||||
|      |  | ||||||
|     // let's fill in inner equations
 |  | ||||||
|     for (int i=1;i<=N;++i) h[i] = points[i].x-points[i-1].x; |  | ||||||
|     std::fill(diag.begin(),diag.end(),2.f); |  | ||||||
|     for (int i=1;i<=N-1;++i) { |  | ||||||
|         mu[i] = h[i]/(h[i]+h[i+1]); |  | ||||||
|         lambda[i] = 1.f - mu[i]; |  | ||||||
|         rhs[i] = 6 * ( float(points[i+1].y-points[i].y  )/(h[i+1]*(points[i+1].x-points[i-1].x)) -   |  | ||||||
|                        float(points[i].y  -points[i-1].y)/(h[i]  *(points[i+1].x-points[i-1].x))   );                        |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     // now fill in the first and last equations, according to boundary conditions:
 |  | ||||||
|     if (boundary_first_derivative) { |  | ||||||
|         const float endpoints_derivative = 0; |  | ||||||
|         lambda[0] = 1; |  | ||||||
|         mu[N]     = 1; |  | ||||||
|         rhs[0] = (6.f/h[1]) * (float(points[0].y-points[1].y)/(points[0].x-points[1].x) - endpoints_derivative); |  | ||||||
|         rhs[N] = (6.f/h[N]) * (endpoints_derivative - float(points[N-1].y-points[N].y)/(points[N-1].x-points[N].x));         |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|         lambda[0] = 0; |  | ||||||
|         mu[N]     = 0; |  | ||||||
|         rhs[0]    = 0; |  | ||||||
|         rhs[N]    = 0; |  | ||||||
|     } |  | ||||||
|          |          | ||||||
|     // the trilinear system is ready to be solved:
 |         // let's fill in inner equations
 | ||||||
|     for (int i=1;i<=N;++i) { |         for (int i=1;i<=N;++i) h[i] = points[i].x-points[i-1].x; | ||||||
|         float multiple = mu[i]/diag[i-1];    // let's subtract proper multiple of above equation
 |         std::fill(diag.begin(),diag.end(),2.f); | ||||||
|         diag[i]-= multiple * lambda[i-1]; |         for (int i=1;i<=N-1;++i) { | ||||||
|         rhs[i] -= multiple * rhs[i-1];         |             mu[i] = h[i]/(h[i]+h[i+1]); | ||||||
|     } |             lambda[i] = 1.f - mu[i]; | ||||||
|     // now the back substitution (vector mu contains invalid values from now on):
 |             rhs[i] = 6 * ( float(points[i+1].y-points[i].y  )/(h[i+1]*(points[i+1].x-points[i-1].x)) - | ||||||
|     rhs[N] = rhs[N]/diag[N]; |                            float(points[i].y  -points[i-1].y)/(h[i]  *(points[i+1].x-points[i-1].x))   ); | ||||||
|     for (int i=N-1;i>=0;--i) |         } | ||||||
|         rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i]; | 
 | ||||||
|      |         // now fill in the first and last equations, according to boundary conditions:
 | ||||||
|      |         if (boundary_first_derivative) { | ||||||
|      |             const float endpoints_derivative = 0; | ||||||
|      |             lambda[0] = 1; | ||||||
|     unsigned int i=1; |             mu[N]     = 1; | ||||||
|     float y=0.f; |             rhs[0] = (6.f/h[1]) * (float(points[0].y-points[1].y)/(points[0].x-points[1].x) - endpoints_derivative); | ||||||
|     for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) {         |             rhs[N] = (6.f/h[N]) * (endpoints_derivative - float(points[N-1].y-points[N].y)/(points[N-1].x-points[N].x)); | ||||||
|         if (splines) { |         } | ||||||
|             if (i<points.size()-1 && points[i].x < x ) { |         else { | ||||||
|                 ++i;  |             lambda[0] = 0; | ||||||
|  |             mu[N]     = 0; | ||||||
|  |             rhs[0]    = 0; | ||||||
|  |             rhs[N]    = 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // the trilinear system is ready to be solved:
 | ||||||
|  |         for (int i=1;i<=N;++i) { | ||||||
|  |             float multiple = mu[i]/diag[i-1];    // let's subtract proper multiple of above equation
 | ||||||
|  |             diag[i]-= multiple * lambda[i-1]; | ||||||
|  |             rhs[i] -= multiple * rhs[i-1]; | ||||||
|  |         } | ||||||
|  |         // now the back substitution (vector mu contains invalid values from now on):
 | ||||||
|  |         rhs[N] = rhs[N]/diag[N]; | ||||||
|  |         for (int i=N-1;i>=0;--i) | ||||||
|  |             rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i]; | ||||||
|  | 
 | ||||||
|  |         unsigned int i=1; | ||||||
|  |         float y=0.f; | ||||||
|  |         for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) { | ||||||
|  |             if (splines) { | ||||||
|  |                 if (i<points.size()-1 && points[i].x < x ) { | ||||||
|  |                     ++i; | ||||||
|  |                 } | ||||||
|  |                 if (points[0].x > x) | ||||||
|  |                     y = points[0].y; | ||||||
|  |                 else | ||||||
|  |                     if (points[N].x < x) | ||||||
|  |                         y = points[N].y; | ||||||
|  |                     else | ||||||
|  |                         y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) + | ||||||
|  |                             (points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] + | ||||||
|  |                             (points[i].y  -rhs[i]  *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i]; | ||||||
|  |                 m_line_to_draw.push_back(y); | ||||||
|             } |             } | ||||||
|             if (points[0].x > x) |             else { | ||||||
|                 y = points[0].y; |                 float x_math = screen_to_math(wxPoint(x,0)).m_x; | ||||||
|             else |                 if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math) | ||||||
|                 if (points[N].x < x) |                     ++i; | ||||||
|                     y = points[N].y; |                 m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y); | ||||||
|                 else  |             } | ||||||
|                     y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) + | 
 | ||||||
|                         (points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] + |             m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1); | ||||||
|                         (points[i].y  -rhs[i]  *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i]; |             m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1); | ||||||
|             m_line_to_draw.push_back(y); |             m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight()); | ||||||
|         } |         } | ||||||
|         else {             |  | ||||||
|             float x_math = screen_to_math(wxPoint(x,0)).m_x; |  | ||||||
|             if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math) |  | ||||||
|                 ++i; |  | ||||||
|             m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y); |  | ||||||
|         } |  | ||||||
|              |  | ||||||
|                      |  | ||||||
|         m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1); |  | ||||||
|         m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1); |  | ||||||
|         m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight()); |  | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
|     wxPostEvent(this->GetParent(), wxCommandEvent(EVT_WIPE_TOWER_CHART_CHANGED)); |     wxPostEvent(this->GetParent(), wxCommandEvent(EVT_WIPE_TOWER_CHART_CHANGED)); | ||||||
|     Refresh(); |     Refresh(); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukas Matena
						Lukas Matena