mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_plater_thumbnail
This commit is contained in:
		
						commit
						8f180a0cc1
					
				
					 11 changed files with 209 additions and 33 deletions
				
			
		|  | @ -113,6 +113,7 @@ void EdgeGrid::Grid::create(const ExPolygonCollection &expolygons, coord_t resol | |||
| // m_contours has been initialized. Now fill in the edge grid.
 | ||||
| void EdgeGrid::Grid::create_from_m_contours(coord_t resolution) | ||||
| { | ||||
| 	assert(resolution > 0); | ||||
| 	// 1) Measure the bounding box.
 | ||||
| 	for (size_t i = 0; i < m_contours.size(); ++ i) { | ||||
| 		const Slic3r::Points &pts = *m_contours[i]; | ||||
|  | @ -1017,8 +1018,139 @@ float EdgeGrid::Grid::signed_distance_bilinear(const Point &pt) const | |||
| 
 | ||||
| 	return f; | ||||
| } | ||||
|   | ||||
| bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment) const { | ||||
| 
 | ||||
| EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt, coord_t search_radius) const  | ||||
| { | ||||
| 	BoundingBox bbox; | ||||
| 	bbox.min = bbox.max = Point(pt(0) - m_bbox.min(0), pt(1) - m_bbox.min(1)); | ||||
| 	bbox.defined = true; | ||||
| 	// Upper boundary, round to grid and test validity.
 | ||||
| 	bbox.max(0) += search_radius; | ||||
| 	bbox.max(1) += search_radius; | ||||
| 	ClosestPointResult result; | ||||
| 	if (bbox.max(0) < 0 || bbox.max(1) < 0) | ||||
| 		return result; | ||||
| 	bbox.max(0) /= m_resolution; | ||||
| 	bbox.max(1) /= m_resolution; | ||||
| 	if ((size_t)bbox.max(0) >= m_cols) | ||||
| 		bbox.max(0) = m_cols - 1; | ||||
| 	if ((size_t)bbox.max(1) >= m_rows) | ||||
| 		bbox.max(1) = m_rows - 1; | ||||
| 	// Lower boundary, round to grid and test validity.
 | ||||
| 	bbox.min(0) -= search_radius; | ||||
| 	bbox.min(1) -= search_radius; | ||||
| 	if (bbox.min(0) < 0) | ||||
| 		bbox.min(0) = 0; | ||||
| 	if (bbox.min(1) < 0) | ||||
| 		bbox.min(1) = 0; | ||||
| 	bbox.min(0) /= m_resolution; | ||||
| 	bbox.min(1) /= m_resolution; | ||||
| 	// Is the interval empty?
 | ||||
| 	if (bbox.min(0) > bbox.max(0) || | ||||
| 		bbox.min(1) > bbox.max(1)) | ||||
| 		return result; | ||||
| 	// Traverse all cells in the bounding box.
 | ||||
| 	double d_min = double(search_radius); | ||||
| 	// Signum of the distance field at pt.
 | ||||
| 	int sign_min = 0; | ||||
| 	double l2_seg_min = 1.; | ||||
| 	for (int r = bbox.min(1); r <= bbox.max(1); ++ r) { | ||||
| 		for (int c = bbox.min(0); c <= bbox.max(0); ++ c) { | ||||
| 			const Cell &cell = m_cells[r * m_cols + c]; | ||||
| 			for (size_t i = cell.begin; i < cell.end; ++ i) { | ||||
| 				const size_t          contour_idx = m_cell_data[i].first; | ||||
| 				const Slic3r::Points &pts         = *m_contours[contour_idx]; | ||||
| 				size_t ipt = m_cell_data[i].second; | ||||
| 				// End points of the line segment.
 | ||||
| 				const Slic3r::Point &p1 = pts[ipt]; | ||||
| 				const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1]; | ||||
| 				const Slic3r::Point v_seg = p2 - p1; | ||||
| 				const Slic3r::Point v_pt  = pt - p1; | ||||
| 				// dot(p2-p1, pt-p1)
 | ||||
| 				int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1)); | ||||
| 				// l2 of seg
 | ||||
| 				int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1)); | ||||
| 				if (t_pt < 0) { | ||||
| 					// Closest to p1.
 | ||||
| 					double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1))); | ||||
| 					if (dabs < d_min) { | ||||
| 						// Previous point.
 | ||||
| 						const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1]; | ||||
| 						Slic3r::Point v_seg_prev = p1 - p0; | ||||
| 						int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1)); | ||||
| 						if (t2_pt > 0) { | ||||
| 							// Inside the wedge between the previous and the next segment.
 | ||||
| 							d_min = dabs; | ||||
| 							// Set the signum depending on whether the vertex is convex or reflex.
 | ||||
| 							int64_t det = int64_t(v_seg_prev(0)) * int64_t(v_seg(1)) - int64_t(v_seg_prev(1)) * int64_t(v_seg(0)); | ||||
| 							assert(det != 0); | ||||
| 							sign_min = (det > 0) ? 1 : -1; | ||||
| 							result.contour_idx = contour_idx; | ||||
| 							result.start_point_idx = ipt; | ||||
| 							result.t = 0.; | ||||
| #ifndef NDEBUG | ||||
| 							Vec2d vfoot = (p1 - pt).cast<double>(); | ||||
| 							double dist_foot = vfoot.norm(); | ||||
| 							double dist_foot_err = dist_foot - d_min; | ||||
| 							assert(std::abs(dist_foot_err) < 1e-7 * d_min); | ||||
| #endif /* NDEBUG */ | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				else if (t_pt > l2_seg) { | ||||
| 					// Closest to p2. Then p2 is the starting point of another segment, which shall be discovered in the same cell.
 | ||||
| 					continue; | ||||
| 				} else { | ||||
| 					// Closest to the segment.
 | ||||
| 					assert(t_pt >= 0 && t_pt <= l2_seg); | ||||
| 					int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1)); | ||||
| 					double d = double(d_seg) / sqrt(double(l2_seg)); | ||||
| 					double dabs = std::abs(d); | ||||
| 					if (dabs < d_min) { | ||||
| 						d_min = dabs; | ||||
| 						sign_min = (d_seg < 0) ? -1 : ((d_seg == 0) ? 0 : 1); | ||||
| 						l2_seg_min = l2_seg; | ||||
| 						result.contour_idx = contour_idx; | ||||
| 						result.start_point_idx = ipt; | ||||
| 						result.t = t_pt; | ||||
| #ifndef NDEBUG | ||||
| 						Vec2d foot = p1.cast<double>() * (1. - result.t / l2_seg_min) + p2.cast<double>() * (result.t / l2_seg_min); | ||||
| 						Vec2d vfoot = foot - pt.cast<double>(); | ||||
| 						double dist_foot = vfoot.norm(); | ||||
| 						double dist_foot_err = dist_foot - d_min; | ||||
| 						assert(std::abs(dist_foot_err) < 1e-7 * d_min); | ||||
| #endif /* NDEBUG */ | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if (result.contour_idx != -1 && d_min <= double(search_radius)) { | ||||
| 		result.distance = d_min * sign_min; | ||||
| 		result.t /= l2_seg_min; | ||||
| 		assert(result.t >= 0. && result.t < 1.); | ||||
| #ifndef NDEBUG | ||||
| 		{ | ||||
| 			const Slic3r::Points &pts = *m_contours[result.contour_idx]; | ||||
| 			const Slic3r::Point  &p1  = pts[result.start_point_idx]; | ||||
| 			const Slic3r::Point  &p2  = pts[(result.start_point_idx + 1 == pts.size()) ? 0 : result.start_point_idx + 1]; | ||||
| 			Vec2d vfoot; | ||||
| 			if (result.t == 0) | ||||
| 				vfoot = p1.cast<double>() - pt.cast<double>(); | ||||
| 			else | ||||
| 				vfoot = p1.cast<double>() * (1. - result.t) + p2.cast<double>() * result.t - pt.cast<double>(); | ||||
| 			double dist_foot = vfoot.norm(); | ||||
| 			double dist_foot_err = dist_foot - std::abs(result.distance); | ||||
| 			assert(std::abs(dist_foot_err) < 1e-7 * std::abs(result.distance)); | ||||
| 		} | ||||
| #endif /* NDEBUG */ | ||||
| 	} else | ||||
| 		result = ClosestPointResult(); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment) const  | ||||
| { | ||||
| 	BoundingBox bbox; | ||||
| 	bbox.min = bbox.max = Point(pt(0) - m_bbox.min(0), pt(1) - m_bbox.min(1)); | ||||
| 	bbox.defined = true; | ||||
|  | @ -1047,7 +1179,7 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu | |||
| 		bbox.min(1) > bbox.max(1)) | ||||
| 		return false; | ||||
| 	// Traverse all cells in the bounding box.
 | ||||
| 	float d_min = search_radius; | ||||
| 	double d_min = double(search_radius); | ||||
| 	// Signum of the distance field at pt.
 | ||||
| 	int sign_min = 0; | ||||
| 	bool on_segment = false; | ||||
|  |  | |||
|  | @ -46,7 +46,19 @@ public: | |||
| 	float signed_distance_bilinear(const Point &pt) const; | ||||
| 
 | ||||
| 	// Calculate a signed distance to the contours in search_radius from the point.
 | ||||
| 	bool signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment = NULL) const; | ||||
| 	struct ClosestPointResult { | ||||
| 		size_t contour_idx  	= size_t(-1); | ||||
| 		size_t start_point_idx  = size_t(-1); | ||||
| 		// Signed distance to the closest point.
 | ||||
| 		double distance 		= std::numeric_limits<double>::max(); | ||||
| 		// Parameter of the closest point on edge starting with start_point_idx <0, 1)
 | ||||
| 		double t 				= 0.; | ||||
| 
 | ||||
| 		bool valid() const { return contour_idx != size_t(-1); } | ||||
| 	}; | ||||
| 	ClosestPointResult closest_point(const Point &pt, coord_t search_radius) const; | ||||
| 
 | ||||
| 	bool signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment = nullptr) const; | ||||
| 
 | ||||
| 	// Calculate a signed distance to the contours in search_radius from the point. If no edge is found in search_radius,
 | ||||
| 	// return an interpolated value from m_signed_distance_field, if it exists.
 | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ target_include_directories(Catch2 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) | |||
| add_library(Catch2::Catch2 ALIAS Catch2) | ||||
| include(Catch) | ||||
| 
 | ||||
| set(CATCH_EXTRA_ARGS "--durations yes" CACHE STRING "Extra arguments for catch2 test suites.") | ||||
| set(CATCH_EXTRA_ARGS "" CACHE STRING "Extra arguments for catch2 test suites.") | ||||
| 
 | ||||
| add_library(test_common INTERFACE) | ||||
| target_compile_definitions(test_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" CATCH_CONFIG_FAST_COMPILE) | ||||
|  |  | |||
							
								
								
									
										54
									
								
								tests/catch_main.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								tests/catch_main.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| #ifndef CATCH_MAIN | ||||
| #define CATCH_MAIN | ||||
| 
 | ||||
| #define CATCH_CONFIG_EXTERNAL_INTERFACES | ||||
| #define CATCH_CONFIG_MAIN | ||||
| #define CATCH_CONFIG_DEFAULT_REPORTER "verboseconsole" | ||||
| #include <catch2/catch.hpp> | ||||
| 
 | ||||
| namespace Catch { | ||||
| struct VerboseConsoleReporter : public ConsoleReporter { | ||||
|     double duration = 0.; | ||||
|     using ConsoleReporter::ConsoleReporter; | ||||
|      | ||||
|     void testCaseStarting(TestCaseInfo const& _testInfo) override | ||||
|     { | ||||
|         Colour::use(Colour::Cyan); | ||||
|         stream << "Testing "; | ||||
|         Colour::use(Colour::None); | ||||
|         stream << _testInfo.name << std::endl; | ||||
|         ConsoleReporter::testCaseStarting(_testInfo); | ||||
|     } | ||||
|      | ||||
|     void sectionStarting(const SectionInfo &_sectionInfo) override | ||||
|     { | ||||
|         if (_sectionInfo.name != currentTestCaseInfo->name) | ||||
|             stream << _sectionInfo.name << std::endl; | ||||
|          | ||||
|         ConsoleReporter::sectionStarting(_sectionInfo); | ||||
|     } | ||||
|      | ||||
|     void sectionEnded(const SectionStats &_sectionStats) override { | ||||
|         duration += _sectionStats.durationInSeconds; | ||||
|         ConsoleReporter::sectionEnded(_sectionStats); | ||||
|     }  | ||||
|      | ||||
|     void testCaseEnded(TestCaseStats const& stats) override | ||||
|     { | ||||
|         if (stats.totals.assertions.allOk()) { | ||||
|             Colour::use(Colour::BrightGreen); | ||||
|             stream << "Passed"; | ||||
|             Colour::use(Colour::None); | ||||
|             stream << " in " << duration << " [seconds]\n" << std::endl; | ||||
|         } | ||||
|          | ||||
|         duration = 0.;             | ||||
|         ConsoleReporter::testCaseEnded(stats); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| CATCH_REGISTER_REPORTER( "verboseconsole", VerboseConsoleReporter ) | ||||
| 
 | ||||
| } // namespace Catch
 | ||||
| 
 | ||||
| #endif // CATCH_MAIN
 | ||||
|  | @ -1,5 +1,5 @@ | |||
| #define CATCH_CONFIG_MAIN | ||||
| #include <catch2/catch.hpp> | ||||
| #include <catch_main.hpp> | ||||
| 
 | ||||
| TEST_CASE("Is example succesful", "[example]") { | ||||
|     REQUIRE(true); | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| #define CATCH_CONFIG_MAIN | ||||
| #include <catch2/catch.hpp> | ||||
| #include <catch_main.hpp> | ||||
| 
 | ||||
| #include "libslic3r/libslic3r.h" | ||||
|  |  | |||
|  | @ -1,9 +1,7 @@ | |||
| #define CATCH_CONFIG_MAIN | ||||
| #include <catch2/catch.hpp> | ||||
| #include <catch_main.hpp> | ||||
| 
 | ||||
| #include <fstream> | ||||
| 
 | ||||
| 
 | ||||
| #include <libnest2d/libnest2d.hpp> | ||||
| #include "printer_parts.hpp" | ||||
| //#include <libnest2d/geometry_traits_nfp.hpp>
 | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| #define CATCH_CONFIG_MAIN | ||||
| #include <catch2/catch.hpp> | ||||
| #include <catch_main.hpp> | ||||
| 
 | ||||
| #include "libslic3r/libslic3r.h" | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| #define CATCH_CONFIG_MAIN | ||||
| #include <catch2/catch.hpp> | ||||
| #include <catch_main.hpp> | ||||
| 
 | ||||
| #include <unordered_set> | ||||
| #include <unordered_map> | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| #define CATCH_CONFIG_MAIN | ||||
| #include <catch2/catch.hpp> | ||||
| #include <catch_main.hpp> | ||||
| 
 | ||||
| #include "libslic3r/Time.hpp" | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,16 +0,0 @@ | |||
| #!/usr/bin/perl | ||||
| 
 | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| use Slic3r::XS; | ||||
| use Test::More tests => 3; | ||||
| 
 | ||||
| { | ||||
|     my $print = Slic3r::Print->new; | ||||
|     isa_ok $print, 'Slic3r::Print'; | ||||
|     isa_ok $print->config, 'Slic3r::Config::Static::Ref'; | ||||
|     isa_ok $print->placeholder_parser, 'Slic3r::GCode::PlaceholderParser::Ref'; | ||||
| } | ||||
| 
 | ||||
| __END__ | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri