You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
11 KiB
280 lines
11 KiB
#include <iostream>
|
|
#include <fstream>
|
|
#include <cstdio>
|
|
#include <vector>
|
|
#include "io_primitive.h"
|
|
#include "math/math_defs.hpp"
|
|
#include "mimalloc.h"
|
|
#include "primitive_descriptor.h"
|
|
#include <solve.h>
|
|
|
|
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;
|
|
}
|