mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Add dedicated tests for support point generation
This commit is contained in:
		
							parent
							
								
									1172dfcb40
								
							
						
					
					
						commit
						4ef52af906
					
				
					 10 changed files with 285 additions and 21 deletions
				
			
		
							
								
								
									
										148
									
								
								tests/sla_print/sla_supptgen_tests.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								tests/sla_print/sla_supptgen_tests.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,148 @@ | |||
| #include <catch2/catch.hpp> | ||||
| #include <test_utils.hpp> | ||||
| 
 | ||||
| #include <libslic3r/ExPolygon.hpp> | ||||
| #include <libslic3r/BoundingBox.hpp> | ||||
| 
 | ||||
| #include "sla_test_utils.hpp" | ||||
| 
 | ||||
| namespace Slic3r { namespace sla { | ||||
| 
 | ||||
| TEST_CASE("Overhanging point should be supported", "[SupGen]") { | ||||
| 
 | ||||
|     // Pyramid with 45 deg slope
 | ||||
|     TriangleMesh mesh = make_pyramid(10.f, 10.f); | ||||
|     mesh.rotate_y(PI); | ||||
|     mesh.require_shared_vertices(); | ||||
|     mesh.WriteOBJFile("Pyramid.obj"); | ||||
| 
 | ||||
|     sla::SupportPoints pts = calc_support_pts(mesh); | ||||
| 
 | ||||
|     // The overhang, which is the upside-down pyramid's edge
 | ||||
|     Vec3f overh{0., 0., -10.}; | ||||
| 
 | ||||
|     REQUIRE(!pts.empty()); | ||||
| 
 | ||||
|     float dist = (overh - pts.front().pos).norm(); | ||||
| 
 | ||||
|     for (const auto &pt : pts) | ||||
|         dist = std::min(dist, (overh - pt.pos).norm()); | ||||
| 
 | ||||
|     // Should require exactly one support point at the overhang
 | ||||
|     REQUIRE(pts.size() > 0); | ||||
|     REQUIRE(dist < 1.f); | ||||
| } | ||||
| 
 | ||||
| double min_point_distance(const sla::SupportPoints &pts) | ||||
| { | ||||
|     sla::PointIndex index; | ||||
| 
 | ||||
|     for (size_t i = 0; i < pts.size(); ++i) | ||||
|         index.insert(pts[i].pos.cast<double>(), i); | ||||
| 
 | ||||
|     auto d = std::numeric_limits<double>::max(); | ||||
|     index.foreach([&d, &index](const sla::PointIndexEl &el) { | ||||
|         auto res = index.nearest(el.first, 2); | ||||
|         for (const sla::PointIndexEl &r : res) | ||||
|             if (r.second != el.second) | ||||
|                 d = std::min(d, (el.first - r.first).norm()); | ||||
|     }); | ||||
| 
 | ||||
|     return d; | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("Overhanging horizontal surface should be supported", "[SupGen]") { | ||||
|     double width = 10., depth = 10., height = 1.; | ||||
| 
 | ||||
|     TriangleMesh mesh = make_cube(width, depth, height); | ||||
|     mesh.translate(0., 0., 5.); // lift up
 | ||||
|     mesh.require_shared_vertices(); | ||||
|     mesh.WriteOBJFile("Cuboid.obj"); | ||||
| 
 | ||||
|     sla::SupportPointGenerator::Config cfg; | ||||
|     sla::SupportPoints pts = calc_support_pts(mesh, cfg); | ||||
| 
 | ||||
|     double mm2 = width * depth; | ||||
| 
 | ||||
|     REQUIRE(!pts.empty()); | ||||
|     REQUIRE(pts.size() * cfg.support_force() > mm2 * cfg.tear_pressure()); | ||||
|     REQUIRE(min_point_distance(pts) >= cfg.minimal_distance); | ||||
| } | ||||
| 
 | ||||
| template<class M> auto&& center_around_bb(M &&mesh) | ||||
| { | ||||
|     auto bb = mesh.bounding_box(); | ||||
|     mesh.translate(-bb.center().template cast<float>()); | ||||
| 
 | ||||
|     return std::forward<M>(mesh); | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("Overhanging edge should be supported", "[SupGen]") { | ||||
|     float width = 10.f, depth = 10.f, height = 5.f; | ||||
| 
 | ||||
|     TriangleMesh mesh = make_prism(width, depth, height); | ||||
|     mesh.rotate_y(PI); // rotate on its back
 | ||||
|     mesh.translate(0., 0., height); | ||||
|     mesh.require_shared_vertices(); | ||||
|     mesh.WriteOBJFile("Prism.obj"); | ||||
| 
 | ||||
|     sla::SupportPointGenerator::Config cfg; | ||||
|     sla::SupportPoints pts = calc_support_pts(mesh, cfg); | ||||
| 
 | ||||
|     REQUIRE(min_point_distance(pts) >= cfg.minimal_distance); | ||||
| 
 | ||||
|     Linef3 overh{ {0.f, -depth / 2.f, 0.f}, {0.f, depth / 2.f, 0.f}}; | ||||
| 
 | ||||
|     // Get all the points closer that 1 mm to the overhanging edge:
 | ||||
|     sla::SupportPoints overh_pts; overh_pts.reserve(pts.size()); | ||||
| 
 | ||||
|     std::copy_if(pts.begin(), pts.end(), std::back_inserter(overh_pts), | ||||
|                  [&overh](const sla::SupportPoint &pt){ | ||||
|                      return line_alg::distance_to(overh, Vec3d{pt.pos.cast<double>()}) < 1.; | ||||
|                  }); | ||||
| 
 | ||||
|     REQUIRE(overh_pts.size() * cfg.support_force() > overh.length() * cfg.tear_pressure()); | ||||
|     REQUIRE(min_point_distance(pts) >= cfg.minimal_distance); | ||||
| } | ||||
| 
 | ||||
| // FIXME: Not working yet
 | ||||
| //TEST_CASE("Hollowed cube should be supported from the inside", "[SupGen][Hollowed]") {
 | ||||
| //    TriangleMesh mesh = make_cube(20., 20., 20.);
 | ||||
| 
 | ||||
| //    hollow_mesh(mesh, HollowingConfig{});
 | ||||
| 
 | ||||
| //    mesh.WriteOBJFile("cube_hollowed.obj");
 | ||||
| 
 | ||||
| //    auto bb = mesh.bounding_box();
 | ||||
| //    auto h  = float(bb.max.z() - bb.min.z());
 | ||||
| //    Vec3f mv = bb.center().cast<float>() - Vec3f{0.f, 0.f, 0.5f * h};
 | ||||
| //    mesh.translate(-mv);
 | ||||
| //    mesh.require_shared_vertices();
 | ||||
| 
 | ||||
| //    sla::SupportPointGenerator::Config cfg;
 | ||||
| //    sla::SupportPoints pts = calc_support_pts(mesh, cfg);
 | ||||
| //    sla::remove_bottom_points(pts, mesh.bounding_box().min.z() + EPSILON);
 | ||||
| 
 | ||||
| //    REQUIRE(!pts.empty());
 | ||||
| //}
 | ||||
| 
 | ||||
| TEST_CASE("Two parallel plates should be supported", "[SupGen][Hollowed]") | ||||
| { | ||||
|     double width = 20., depth = 20., height = 1.; | ||||
| 
 | ||||
|     TriangleMesh mesh = center_around_bb(make_cube(width + 5., depth + 5., height)); | ||||
|     TriangleMesh mesh_high = center_around_bb(make_cube(width, depth, height)); | ||||
|     mesh_high.translate(0., 0., 10.); // lift up
 | ||||
|     mesh.merge(mesh_high); | ||||
|     mesh.require_shared_vertices(); | ||||
| 
 | ||||
|     mesh.WriteOBJFile("parallel_plates.obj"); | ||||
| 
 | ||||
|     sla::SupportPointGenerator::Config cfg; | ||||
|     sla::SupportPoints pts = calc_support_pts(mesh, cfg); | ||||
|     sla::remove_bottom_points(pts, mesh.bounding_box().min.z() + EPSILON); | ||||
| 
 | ||||
|     REQUIRE(!pts.empty()); | ||||
| } | ||||
| 
 | ||||
| }} // namespace Slic3r::sla
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros