5#include "testing/testing.h"
11#define USE_COMBINATIONS_ALL
34 const float poly[][2],
40 POLYFILL2D_TEST_IS_DEGENERATE = (1 << 0),
41 POLYFILL2D_TEST_NO_ZERO_AREA_TRIS = (1 << 1),
42 POLYFILL2D_TEST_NOP = 0,
48#define TRI_ERROR_VALUE uint(-1)
53 for (i = 0; i < tris_num; i++) {
55 for (j = 0; j < 3; j++) {
74 int *used_num = (
int *)
MEM_callocN(poly_num *
sizeof(
int), __func__);
75 for (i = 0; i < tris_num; i++) {
77 for (j = 0; j < 3; j++) {
79 used_num[tris[i][j]] += 1;
81 EXPECT_NE(tris[i][0], tris[i][1]);
82 EXPECT_NE(tris[i][1], tris[i][2]);
83 EXPECT_NE(tris[i][2], tris[i][0]);
85 for (i = 0; i < poly_num; i++) {
86 EXPECT_NE(0, used_num[i]);
98 for (i = 0; i < tris_num; i++) {
100 for (j = 0; j < 3; j++) {
101 const uint v1 = tris[i][j];
102 const uint v2 = tris[i][(j + 1) % 3];
104 {v1,
v2}, [](
int *value) { *value = 1; }, [](
int *value) { (*value)++; });
109 for (i = 0; i < poly_num; i++) {
111 const uint v2 = (i + 1) % poly_num;
112 EXPECT_TRUE(edgehash.
contains({v1, v2}));
116 for (
const int value : edgehash.
values()) {
117 EXPECT_TRUE(
ELEM(value, 1, 2));
126 const uint tris[][3],
131 for (i = 0; i < tris_num; i++) {
132 float winding_test =
cross_tri_v2(poly[tris[i][0]], poly[tris[i][1]], poly[tris[i][2]]);
133 if (
fabsf(winding_test) > FLT_EPSILON) {
134 count[winding_test < 0.0f] += 1;
145 const uint tris[][3],
150 float area_total_tris = 0.0f;
151 const float eps_abs = 0.00001f;
152 const float eps = area_total > 1.0f ? (area_total * eps_abs) : eps_abs;
153 for (i = 0; i < tris_num; i++) {
154 area_total_tris +=
area_tri_v2(poly[tris[i][0]], poly[tris[i][1]], poly[tris[i][2]]);
156 EXPECT_NEAR(area_total, area_total_tris,
eps);
164 const uint tris[][3],
169 for (i = 0; i < tris_num; i++) {
170 if (
area_tri_v2(poly[tris[i][0]], poly[tris[i][1]], poly[tris[i][2]]) < 1e-6f) {
184 const float poly[][2],
186 const uint tris[][3],
191 if (!(test_flag & POLYFILL2D_TEST_IS_DEGENERATE)) {
198 if (test_flag & POLYFILL2D_TEST_NO_ZERO_AREA_TRIS) {
207 const float poly[][2],
236 const float poly[][2],
242 for (
int flip_x = 0; flip_x < 2; flip_x++) {
243 for (
int flip_y = 0; flip_y < 2; flip_y++) {
244 float sign_x = flip_x ? -1.0f : 1.0f;
245 float sign_y = flip_y ? -1.0f : 1.0f;
246 for (
int i = 0; i < poly_num; i++) {
247 poly_copy[i][0] = poly[i][0] * sign_x;
248 poly_copy[i][1] = poly[i][1] * sign_y;
256#ifdef USE_COMBINATIONS_ALL
259 const float poly[][2],
269 memcpy(poly_copy, poly,
sizeof(
float[2]) * poly_num);
271 for (poly_reverse = 0; poly_reverse < 2; poly_reverse++) {
278 for (poly_cycle = 0; poly_cycle < poly_num; poly_cycle++) {
284 memmove(&poly_copy[0], &poly_copy[1], (poly_num - 1) *
sizeof(
float[2]));
294 const float poly[][2],
303#define TEST_POLYFILL_TEMPLATE_STATIC(poly, test_flag) \
305 uint tris[POLY_TRI_COUNT(ARRAY_SIZE(poly))][3]; \
306 const uint poly_num = ARRAY_SIZE(poly); \
307 const uint tris_num = ARRAY_SIZE(tris); \
308 const char *id = typeid(*this).name(); \
310 test_polyfill_template_main(id, test_flag, poly, poly_num, tris, tris_num); \
317#ifdef USE_OBJ_PREVIEW
319 const float poly[][2],
321 const uint tris[][3],
330 f = fopen(path,
"w");
335 for (i = 0; i < poly_num; i++) {
336 fprintf(f,
"v %f %f 0.0\n",
UNPACK2(poly[i]));
339 for (i = 0; i < tris_num; i++) {
340 fprintf(f,
"f %u %u %u\n",
UNPACK3_EX(1 +, tris[i], ));
347 const float poly[][2],
349 const uint tris[][3],
353 (void)poly, (
void)poly_num;
354 (void)tris, (
void)tris_num;
398#define POLY_TRI_COUNT(len) ((len)-2)
403 const float poly[][2] = {{0, 0}, {0, 1}, {1, 0}};
410 const float poly[][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
417 const float poly[][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
424 const float poly[][2] = {{0, 0}, {0.6f, 0.4f}, {1, 0}, {0.5f, 1}};
429TEST(polyfill2d, StarfleetDegenerate)
431 const float poly[][2] = {{0, 0}, {0.6f, 0.4f}, {0.6f, 0.4f}, {1, 0}, {0.5f, 1}};
438 const float poly[][2] = {{0, 0}, {1, 0}, {2, 0}};
445 const float poly[][2] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}};
450TEST(polyfill2d, UnorderedColinear)
452 const float poly[][2] = {{0, 0}, {1, 1}, {2, 0}, {3, 1}, {4, 0}};
459 const float poly[][2] = {
479 const float poly[][2] = {{4, 0}, {5, 3}, {8, 4}, {5, 5}, {4, 8}, {3, 5}, {0, 4}, {3, 3}};
486 const float poly[][2] = {
487 {1, 0}, {2, 0}, {3, 1}, {3, 3}, {2, 3}, {2, 1}, {1, 1}, {1, 3}, {0, 3}, {0, 1}};
494 const float poly[][2] = {
518 const float poly[][2] = {
541 const float poly[][2] = {{0, 0}, {1, 1}, {2, -1}, {3, 1}, {4, 0}};
548 const float poly[][2] = {
568 const float poly[][2] = {
588 const float poly[][2] = {
589 {190, 480}, {140, 180}, {310, 100}, {330, 390}, {290, 390}, {280, 260}, {220, 260},
590 {220, 430}, {370, 430}, {350, 30}, {50, 30}, {160, 560}, {730, 510}, {710, 20},
591 {410, 30}, {470, 440}, {640, 410}, {630, 140}, {590, 140}, {580, 360}, {510, 370},
592 {510, 60}, {650, 70}, {660, 450}, {190, 480},
600 const float poly[][2] = {
616 const float poly[][2] = {
617 {72.42465f, 197.07095f},
618 {78.485535f, 189.92776f},
619 {86.12059f, 180.92929f},
620 {99.68253f, 164.94557f},
621 {105.24325f, 165.79604f},
622 {107.21862f, 166.09814f},
623 {112.41958f, 162.78253f},
624 {113.73238f, 161.94562f},
625 {123.29477f, 167.93805f},
626 {126.70667f, 170.07617f},
627 {73.22717f, 199.51062f},
636 const float poly[][2] = {
637 {2400.0f, 480.0f}, {2400.0f, 176.0f}, {1920.0f, 480.0f},
638 {1920.0459f, 484.22314f}, {1920.1797f, 487.91016f}, {1920.3955f, 491.0874f},
639 {1920.6875f, 493.78125f}, {1921.0498f, 496.01807f}, {1921.4766f, 497.82422f},
640 {1921.9619f, 499.22607f}, {1922.5f, 500.25f}, {1923.085f, 500.92236f},
641 {1923.7109f, 501.26953f}, {1924.3721f, 501.31787f}, {1925.0625f, 501.09375f},
642 {1925.7764f, 500.62354f}, {1926.5078f, 499.9336f}, {1927.251f, 499.0503f},
643 {1928.0f, 498.0f}, {1928.749f, 496.80908f}, {1929.4922f, 495.5039f},
644 {1930.2236f, 494.11084f}, {1930.9375f, 492.65625f}, {1931.6279f, 491.1665f},
645 {1932.2891f, 489.66797f}, {1932.915f, 488.187f}, {1933.5f, 486.75f},
646 {1934.0381f, 485.3833f}, {1934.5234f, 484.11328f}, {1934.9502f, 482.9663f},
647 {1935.3125f, 481.96875f}, {1935.6045f, 481.14697f}, {1935.8203f, 480.52734f},
648 {1935.9541f, 480.13623f}, {1936.0f, 480.0f}};
655 const float poly[][2] = {
656 {3.914329f, 1.9008259f},
657 {4.414321f, 1.903619f},
658 {4.8973203f, 1.9063174f},
659 {5.4979978f, 1.9096732f},
668 const float poly[][2] = {
669 {3.914329f, 1.9008259f},
670 {4.414321f, 1.903619f},
671 {4.8973203f, 1.9063174f},
672 {5.4979978f, 1.9096732f},
679TEST(polyfill2d, IssueT40777_colinear)
681 const float poly[][2] = {
682 {0.7, 0.37}, {0.7, 0}, {0.76, 0}, {0.76, 0.4}, {0.83, 0.4}, {0.83, 0}, {0.88, 0},
683 {0.88, 0.4}, {0.94, 0.4}, {0.94, 0}, {1, 0}, {1, 0.4}, {0.03, 0.62}, {0.03, 0.89},
684 {0.59, 0.89}, {0.03, 1}, {0, 1}, {0, 0}, {0.03, 0}, {0.03, 0.37},
690TEST(polyfill2d, IssueT41986_axis_align)
692 const float poly[][2] = {
693 {-0.25, -0.07}, {-0.25, 0.27}, {-1.19, 0.14}, {-0.06, 0.73}, {0.17, 1.25},
694 {-0.25, 1.07}, {-0.38, 1.02}, {-0.25, 0.94}, {-0.40, 0.90}, {-0.41, 0.86},
695 {-0.34, 0.83}, {-0.25, 0.82}, {-0.66, 0.73}, {-0.56, 1.09}, {-0.25, 1.10},
696 {0.00, 1.31}, {-0.03, 1.47}, {-0.25, 1.53}, {0.12, 1.62}, {0.36, 1.07},
697 {0.12, 0.67}, {0.29, 0.57}, {0.44, 0.45}, {0.57, 0.29}, {0.66, 0.12},
698 {0.68, 0.06}, {0.57, -0.36}, {-0.25, -0.37}, {0.49, -0.74}, {-0.59, -1.21},
699 {-0.25, -0.15}, {-0.46, -0.52}, {-1.08, -0.83}, {-1.45, -0.33}, {-1.25, -0.04}};
705TEST(polyfill2d, IssueT52834_axis_align_co_linear)
707 const float poly[][2] = {
708 {40, 0}, {36, 0}, {36, 5}, {35, 5}, {35, 0}, {30, 0}, {30, 5}, {29, 5},
709 {29, 0}, {24, 0}, {24, 3}, {23, 4}, {23, 0}, {18, 0}, {18, 5}, {17, 5},
710 {17, 0}, {12, 0}, {12, 5}, {11, 5}, {11, 0}, {6, 0}, {6, 5}, {5, 5},
711 {5, 0}, {0, 0}, {0, 5}, {-1, 5}, {-1, 0}, {-6, 0}, {-9, -3}, {-6, -3},
712 {-6, -2}, {-1, -2}, {0, -2}, {5, -2}, {6, -2}, {11, -2}, {12, -2}, {17, -2},
713 {18, -2}, {23, -2}, {24, -2}, {29, -2}, {30, -2}, {35, -2}, {36, -2}, {40, -2},
721TEST(polyfill2d, IssueT67109_axis_align_co_linear_a)
723 const float poly[][2] = {
724 {3.2060661, -11.438997},
725 {2.8720665, -5.796999},
726 {-2.8659325, -5.796999},
727 {-2.8659325, -8.307999},
728 {-3.2549324, -11.438997},
729 {-2.8659325, -5.4869995},
730 {2.8720665, -5.4869995},
731 {2.8720665, -2.9759989},
732 {2.8720665, -2.6659985},
733 {2.8720665, -0.15499878},
739TEST(polyfill2d, IssueT67109_axis_align_co_linear_b)
741 const float poly[][2] = {
742 {32.41416, -12.122593},
743 {28.094929, -8.477332},
744 {24.141455, -12.636018},
745 {25.96133, -14.366093},
746 {27.96254, -16.805279},
747 {23.916779, -12.422427},
748 {27.870255, -8.263744},
749 {26.050375, -6.533667},
750 {25.825695, -6.320076},
751 {24.00582, -4.5899982},
757TEST(polyfill2d, IssueT67109_axis_align_co_linear_c)
759 const float poly[][2] = {
760 {-67.10034, 43.677097},
761 {-63.253956, 61.399143},
762 {-80.98382, 66.36057},
763 {-83.15499, 58.601795},
764 {-87.06422, 49.263668},
765 {-80.71576, 67.31843},
766 {-62.985912, 62.35701},
767 {-60.81475, 70.11576},
768 {-60.546703, 71.07365},
769 {-58.37554, 78.83239},
776TEST(polyfill2d, Issue103913_axis_align_co_linear_no_zero_area_tri)
778 const float poly[][2] = {
779 {-10, 0}, {-10, 2}, {-8, 2}, {-6, 2}, {-4, 2}, {-2, 2}, {-2, 4}, {-2, 6},
780 {-2, 8}, {-2, 10}, {0, 10}, {2, 10}, {2, 8}, {2, 6}, {2, 4}, {2, 2},
781 {4, 2}, {6, 2}, {8, 2}, {10, 2}, {10, 0}, {10, -2}, {8, -2}, {6, -2},
782 {4, -2}, {2, -2}, {2, -4}, {2, -6}, {2, -8}, {2, -10}, {0, -10}, {-2, -10},
783 {-2, -8}, {-2, -6}, {-2, -4}, {-2, -2}, {-4, -2}, {-6, -2}, {-8, -2}, {-10, -2},
Generic array manipulation API.
#define BLI_array_reverse(arr, arr_len)
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
A min-heap / priority queue ADT.
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
Heap * BLI_heap_new_ex(unsigned int reserve_num) ATTR_WARN_UNUSED_RESULT
MINLINE float area_tri_v2(const float v1[2], const float v2[2], const float v3[2])
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2])
float area_poly_v2(const float verts[][2], unsigned int nr)
MINLINE void copy_v2_v2(float r[2], const float a[2])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_POLYFILL_ARENA_SIZE
void BLI_polyfill_calc(const float(*coords)[2], unsigned int coords_num, int coords_sign, unsigned int(*r_tris)[3])
#define BLI_POLYFILL_ALLOC_NGON_RESERVE
void BLI_polyfill_beautify(const float(*coords)[2], unsigned int coords_num, unsigned int(*tris)[3], struct MemArena *arena, struct Heap *eheap)
static void test_polyfill_template(const char *id, const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, uint tris[][3], const uint tris_num)
static void test_polyfill_template_main(const char *id, const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, uint tris[][3], const uint tris_num)
static void polyfill_to_obj(const char *id, const float poly[][2], const uint poly_num, const uint tris[][3], const uint tris_num)
static void test_valid_polyfill_prepare(uint tris[][3], uint tris_num)
#define TEST_POLYFILL_TEMPLATE_STATIC(poly, test_flag)
TEST(polyfill2d, TriangleCCW)
static void test_polyfill_area_tri_nonzero(const float poly[][2], const uint, const uint tris[][3], const uint tris_num)
static void test_polyfill_template_check(const char *id, const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, const uint tris[][3], const uint tris_num)
static void test_polyfill_topology(const float[][2], const uint poly_num, const uint tris[][3], const uint tris_num)
static void test_polyfill_simple(const float[][2], const uint poly_num, const uint tris[][3], const uint tris_num)
static void test_polyfill_template_flip_sign(const char *id, const ePolyFill2DTestFlag test_flag, const float poly[][2], const uint poly_num, uint tris[][3], const uint tris_num)
enum ePolyFill2DTestFlag { POLYFILL2D_TEST_IS_DEGENERATE=(1<< 0), POLYFILL2D_TEST_NO_ZERO_AREA_TRIS=(1<< 1), POLYFILL2D_TEST_NOP=0, } ePolyFill2DTestFlag
static void test_polyfill_winding(const float poly[][2], const uint, const uint tris[][3], const uint tris_num)
static void test_polyfill_area(const float poly[][2], const uint poly_num, const uint tris[][3], const uint tris_num)
#define SNPRINTF(dst, format,...)
#define UNPACK3_EX(pre, a, post)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
const Value & lookup(const Key &key) const
ValueIterator values() const
bool contains(const Key &key) const
auto add_or_modify(const Key &key, const CreateValueF &create_value, const ModifyValueF &modify_value) -> decltype(create_value(nullptr))
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)