#include #include #include #include #include "io_primitive.h" #include "math/math_defs.hpp" #include "mimalloc.h" #include "primitive_descriptor.h" #include void export_obj(const char* filename, const polymesh_t& mesh) { std::ofstream f(filename); if (!f) { std::cerr << "Cannot open " << filename << std::endl; return; } for (uint32_t i = 0; i < mesh.num_vertices; ++i) { auto& v = mesh.vertices[i]; f << "v " << v.x << " " << v.y << " " << v.z << "\n"; } uint32_t offset = 0; for (uint32_t fi = 0; fi < mesh.num_faces; ++fi) { uint32_t count = mesh.vertex_counts[fi]; f << "f"; for (uint32_t j = 0; j < count; ++j) f << " " << (mesh.faces[offset + j] + 1); f << "\n"; offset += count; } std::cout << " -> " << filename << ": " << mesh.num_vertices << " verts, " << mesh.num_faces << " faces" << std::endl; } void run_test_case(const char* name, polyline_pattern_descriptor_t& pattern_desc, polyline_axis_descriptor_t& axis_desc) { auto dc = create_primitive_data_center(); auto pat = create_pattern(dc, &pattern_desc, PATTERN_TYPE_POLYLINE); auto ax = create_extrude_axis(dc, &axis_desc, AXIS_TYPE_EXTRUDE_POLYLINE); auto ext = create_param_primitive(&ax, &pat, dc, PRIMITIVE_TYPE_EXTRUDE); auto rt = create_blobtree(); blobtree_add_primitive_node(rt, ext); auto baked = bake_blobtree(rt); destroy_blobtree(rt); s_settings s{}; s.resolution = 32; s.scene_aabb_margin = 1e-5; s.restricted_primitive_bounding_test = true; s.integrand_density = 32; auto solver = create_solver(baked, s); auto result = generate_polymesh(solver); std::cout << name << ": " << (result.success ? "OK" : "FAIL") << " verts=" << result.mesh.num_vertices << " faces=" << result.mesh.num_faces << std::endl; char filename[256]; snprintf(filename, sizeof(filename), "test_extrude_%s.obj", name); export_obj(filename, result.mesh); destroy_solver(solver); destroy_baked_blobtree(baked); destroy_primitive(ext); destroy_primitive_data_center(dc); } int main() { const double b_quarter = std::tan(pi / 8); // tan(theta/4), theta=pi/2 -> quarter circle // --- Curved axis: quarter-circle arc from (0,0,0) to (0,1,1) --- polyline_axis_descriptor_t axis_curved{}; std::vector axis_pts_curved{ vector3d{0, 0, 0}, vector3d{0, 1, 1} }; axis_curved.point_number = 2; axis_curved.points = axis_pts_curved.data(); std::vector axis_blg_curved{ b_quarter }; axis_curved.bulge_number = 1; axis_curved.bulges = axis_blg_curved.data(); axis_curved.reference_normal = {1, 0, 0}; axis_curved.is_closed = false; // --- Straight axis: from (0,0,0) to (0,0,1) --- polyline_axis_descriptor_t axis_straight{}; std::vector axis_pts_straight{ vector3d{0, 0, 0}, vector3d{0, 0, 1} }; axis_straight.point_number = 2; axis_straight.points = axis_pts_straight.data(); std::vector axis_blg_straight{ 0. }; axis_straight.bulge_number = 1; axis_straight.bulges = axis_blg_straight.data(); axis_straight.reference_normal = {1, 0, 0}; axis_straight.is_closed = false; // ================================================================== // Test 1: Original semicircle (reference, all arcs, legacy bulge=1) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.1, 0}, vector2d{.1, 0}, vector2d{-.1, 0} }; pat.point_number = 3; pat.points = pts.data(); std::vector blg{ 1., 1. }; pat.bulge_number = 2; pat.bulges = blg.data(); run_test_case("01_original_semicircle", pat, axis_curved); } // ================================================================== // Test 2: Rectangle (all lines, bulge=0) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.1, -.1}, vector2d{.1, -.1}, vector2d{.1, .1}, vector2d{-.1, .1}, vector2d{-.1, -.1} }; pat.point_number = 5; pat.points = pts.data(); std::vector blg{ 0., 0., 0., 0. }; pat.bulge_number = 4; pat.bulges = blg.data(); run_test_case("02_rectangle", pat, axis_curved); } // ================================================================== // Test 3: Curved diamond (4 quarter-circle arcs, total theta=2pi) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.12, 0}, vector2d{0, .12}, vector2d{.12, 0}, vector2d{0, -.12}, vector2d{-.12, 0} }; pat.point_number = 5; pat.points = pts.data(); std::vector blg{ b_quarter, b_quarter, b_quarter, b_quarter }; pat.bulge_number = 4; pat.bulges = blg.data(); run_test_case("03_curved_diamond", pat, axis_curved); } // ================================================================== // Test 4: Rectangle with one rounded side (3 lines + 1 arc) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.12, -.08}, vector2d{.12, -.08}, vector2d{.12, .08}, vector2d{-.12, .08}, vector2d{-.12, -.08} }; pat.point_number = 5; pat.points = pts.data(); std::vector blg{ 0., 0., 0., b_quarter }; pat.bulge_number = 4; pat.bulges = blg.data(); run_test_case("04_rect_one_arc", pat, axis_curved); } // ================================================================== // Test 5: Alternating line-arc hexagon (3 lines + 3 quarter arcs) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.10, -.05}, vector2d{0., -.10}, vector2d{.10, -.05}, vector2d{.10, .05}, vector2d{0., .10}, vector2d{-.10, .05}, vector2d{-.10, -.05} }; pat.point_number = 7; pat.points = pts.data(); std::vector blg{ 0., b_quarter, 0., b_quarter, 0., b_quarter }; pat.bulge_number = 6; pat.bulges = blg.data(); run_test_case("05_alternating_hex", pat, axis_curved); } // ================================================================== // Test 6: Rectangle on straight axis (baseline, all lines) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.1, -.1}, vector2d{.1, -.1}, vector2d{.1, .1}, vector2d{-.1, .1}, vector2d{-.1, -.1} }; pat.point_number = 5; pat.points = pts.data(); std::vector blg{ 0., 0., 0., 0. }; pat.bulge_number = 4; pat.bulges = blg.data(); run_test_case("06_rect_straight_axis", pat, axis_straight); } // ================================================================== // Test 7: Curved diamond on straight axis // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.12, 0}, vector2d{0, .12}, vector2d{.12, 0}, vector2d{0, -.12}, vector2d{-.12, 0} }; pat.point_number = 5; pat.points = pts.data(); std::vector blg{ b_quarter, b_quarter, b_quarter, b_quarter }; pat.bulge_number = 4; pat.bulges = blg.data(); run_test_case("07_curved_diamond_straight", pat, axis_straight); } // ================================================================== // Test 8: Pill/Stadium shape (2 lines + 2 quarter arcs, straight axis) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.06, -.12}, vector2d{-.06, .12}, vector2d{ .06, .12}, vector2d{ .06, -.12}, vector2d{-.06, -.12} }; pat.point_number = 5; pat.points = pts.data(); std::vector blg{ 0., b_quarter, 0., b_quarter }; pat.bulge_number = 4; pat.bulges = blg.data(); run_test_case("08_pill_shape", pat, axis_straight); } // ================================================================== // Test 9: Mixed octagon (4 lines + 4 arcs, straight axis) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.12, -.08}, vector2d{-.06, -.12}, vector2d{ .06, -.12}, vector2d{ .12, -.08}, vector2d{ .12, .08}, vector2d{ .06, .12}, vector2d{-.06, .12}, vector2d{-.12, .08}, vector2d{-.12, -.08} }; pat.point_number = 9; pat.points = pts.data(); std::vector blg{ b_quarter, 0., b_quarter, 0., b_quarter, 0., b_quarter, 0. }; pat.bulge_number = 8; pat.bulges = blg.data(); run_test_case("09_mixed_octagon", pat, axis_straight); } // ================================================================== // Test 10: Rounded triangle (2 lines + 1 arc, straight axis) // ================================================================== { polyline_pattern_descriptor_t pat{}; pat.anchor = {0, 0}; std::vector pts{ vector2d{-.10, -.10}, vector2d{.10, -.10}, vector2d{-.10, .10}, vector2d{-.10, -.10} }; pat.point_number = 4; pat.points = pts.data(); std::vector blg{ 0., b_quarter, 0. }; pat.bulge_number = 3; pat.bulges = blg.data(); run_test_case("10_rounded_triangle", pat, axis_straight); } std::cout << "\nAll tests completed." << std::endl; return 0; }