1#include "taichi/ui/gui/gui.h"
2
3namespace taichi {
4
5Vector2 Canvas::Line::vertices[128];
6
7void Canvas::triangles_batched(int n,
8 std::size_t a_,
9 std::size_t b_,
10 std::size_t c_,
11 uint32 color_single,
12 std::size_t color_array) {
13 auto a = (real *)a_;
14 auto b = (real *)b_;
15 auto c = (real *)c_;
16 auto color_arr = (uint32 *)color_array;
17 for (int i = 0; i < n; i++) {
18 auto clr = color_single;
19 if (color_arr) {
20 clr = color_arr[i];
21 }
22 triangle_single(a[i * 2], a[i * 2 + 1], b[i * 2], b[i * 2 + 1], c[i * 2],
23 c[i * 2 + 1], clr);
24 }
25}
26
27void Canvas::paths_batched(int n,
28 std::size_t a_,
29 std::size_t b_,
30 uint32 color_single,
31 std::size_t color_array,
32 real radius_single,
33 std::size_t radius_array) {
34 auto a = (real *)a_;
35 auto b = (real *)b_;
36 auto color_arr = (uint32 *)color_array;
37 auto radius_arr = (real *)radius_array;
38 for (int i = 0; i < n; i++) {
39 auto r = radius_single;
40 if (radius_arr) {
41 r = radius_arr[i];
42 }
43 auto clr = color_single;
44 if (color_arr) {
45 clr = color_arr[i];
46 }
47 // FIXME: path_single seems not displaying correct without the 1e-6 term:
48 path_single(a[i * 2], a[i * 2 + 1], b[i * 2] + 1e-6 * (i % 18 + 6),
49 b[i * 2 + 1], clr, r);
50 }
51}
52
53void Canvas::circles_batched(int n,
54 std::size_t x_,
55 uint32 color_single,
56 std::size_t color_array,
57 real radius_single,
58 std::size_t radius_array) {
59 auto x = (real *)x_;
60 auto color_arr = (uint32 *)color_array;
61 auto radius_arr = (real *)radius_array;
62 for (int i = 0; i < n; i++) {
63 auto r = radius_single;
64 if (radius_arr) {
65 r = radius_arr[i];
66 }
67 auto c = color_single;
68 if (color_arr) {
69 c = color_arr[i];
70 }
71 circle(x[i * 2], x[i * 2 + 1]).radius(r).color(c).finish();
72 }
73}
74
75void Canvas::circle_single(real x, real y, uint32 color, real radius) {
76 circle(x, y).radius(radius).color(color).finish();
77}
78
79void Canvas::path_single(real x0,
80 real y0,
81 real x1,
82 real y1,
83 uint32 color,
84 real radius) {
85 path(Vector2(x0, y0), Vector2(x1, y1)).radius(radius).color(color).finish();
86}
87
88void Canvas::triangle(Vector2 a, Vector2 b, Vector2 c, Vector4 color) {
89 a = transform(a);
90 b = transform(b);
91 c = transform(c);
92
93 // real points[3] = {a, b, c};
94 // std::sort(points, points + 3, [](const Vector2 &a, const Vector2 &b) {
95 // return a.y < b.y;
96 //});
97 Vector2 limits[2];
98 limits[0].x = min(a.x, min(b.x, c.x));
99 limits[0].y = min(a.y, min(b.y, c.y));
100 limits[1].x = max(a.x, max(b.x, c.x));
101 limits[1].y = max(a.y, max(b.y, c.y));
102 for (int i = (int)std::floor(limits[0].x); i < (int)std::ceil(limits[1].x);
103 i++) {
104 for (int j = (int)std::floor(limits[0].y); j < (int)std::ceil(limits[1].y);
105 j++) {
106 Vector2 pixel(i + 0.5_f, j + 0.5_f);
107 bool inside_a = cross(pixel - a, b - a) <= 0;
108 bool inside_b = cross(pixel - b, c - b) <= 0;
109 bool inside_c = cross(pixel - c, a - c) <= 0;
110
111 // cover both clockwise and counterclockwise case for vertices [a, b, c]
112 bool inside_triangle = (inside_a == inside_b) && (inside_a == inside_c);
113
114 if (inside_triangle && img.inside(i, j)) {
115 img[i][j] = color;
116 }
117 }
118 }
119}
120
121void Canvas::triangle_single(real x0,
122 real y0,
123 real x1,
124 real y1,
125 real x2,
126 real y2,
127 uint32 color_hex) {
128 auto a = Vector2(x0, y0);
129 auto b = Vector2(x1, y1);
130 auto c = Vector2(x2, y2);
131 auto color = color_from_hex(color_hex);
132 triangle(a, b, c, color);
133}
134
135} // namespace taichi
136