3 #include "testing/testing.h"
18 #define DO_REGULAR_TESTS 1
19 #define DO_PERF_TESTS 0
22 namespace blender::meshintersect::tests {
24 constexpr
bool DO_OBJ =
false;
33 static constexpr
int MAX_FACE_LEN = 1000;
35 static int edge_index(
int face_index,
int facepos)
37 return face_index * MAX_FACE_LEN + facepos;
40 static std::pair<int, int> face_and_pos_for_edge_index(
int e_index)
42 return std::pair<int, int>(e_index / MAX_FACE_LEN, e_index % MAX_FACE_LEN);
51 IMeshBuilder(
const char *spec)
53 std::istringstream ss(spec);
56 std::istringstream hdrss(line);
59 if (nv == 0 || nf == 0) {
62 arena.reserve(nv, nf);
63 Vector<const Vert *>
verts;
67 while (v_index < nv && spec_ok && getline(ss, line)) {
68 std::istringstream iss(line);
72 iss >> p0 >> p1 >> p2;
73 spec_ok = !iss.fail();
75 verts.append(arena.add_or_find_vert(mpq3(p0, p1, p2), v_index));
83 while (f_index < nf && spec_ok && getline(ss, line)) {
84 std::istringstream fss(line);
85 Vector<const Vert *> face_verts;
86 Vector<int> edge_orig;
88 while (spec_ok && fss >> v_index) {
89 if (v_index < 0 || v_index >= nv) {
93 face_verts.append(
verts[v_index]);
94 edge_orig.append(edge_index(f_index, fpos));
101 Face *facep = arena.add_face(face_verts, f_index, edge_orig);
110 std::cout <<
"Bad spec: " << spec;
113 imesh = IMesh(
faces);
120 static const Face *find_tri_with_verts(
const IMesh &
mesh,
125 Face f_arg({v0,
v1,
v2}, 0, NO_INDEX);
126 for (
const Face *f :
mesh.faces()) {
127 if (f->cyclic_equal(f_arg)) {
135 static int count_tris_with_verts(
const IMesh &
mesh,
const Vert *v0,
const Vert *
v1,
const Vert *
v2)
137 Face f_arg({v0,
v1,
v2}, 0, NO_INDEX);
139 for (
const Face *f :
mesh.faces()) {
140 if (f->cyclic_equal(f_arg)) {
149 static int find_edge_pos_in_tri(
const Vert *v0,
const Vert *
v1,
const Face *f)
151 for (
int pos : f->index_range()) {
152 int nextpos = f->next_pos(
pos);
153 if (((*f)[
pos] == v0 && (*f)[nextpos] ==
v1) || ((*f)[
pos] ==
v1 && (*f)[nextpos] == v0)) {
154 return static_cast<int>(
pos);
160 # if DO_REGULAR_TESTS
163 Vector<const Vert *>
verts;
164 Vector<Face *>
faces;
167 verts.append(arena.add_or_find_vert(mpq3(0, 0, 1), 0));
168 verts.append(arena.add_or_find_vert(mpq3(1, 0, 1), 1));
169 verts.append(arena.add_or_find_vert(mpq3(0.5, 1, 1), 2));
170 faces.append(arena.add_face(
verts, 0, {10, 11, 12}));
174 EXPECT_TRUE(f->is_tri());
177 TEST(mesh_intersect, OneTri)
179 const char *spec = R
"(3 1
186 IMeshBuilder mb(spec);
187 IMesh imesh = trimesh_self_intersect(mb.imesh, &mb.arena);
188 imesh.populate_vert();
191 const Face &f_in = *mb.imesh.face(0);
192 const Face &f_out = *imesh.face(0);
194 for (
int i = 0; i < 3; ++i) {
196 EXPECT_EQ(f_in.edge_orig[i], f_out.edge_orig[i]);
200 TEST(mesh_intersect, TriTri)
202 const char *spec = R
"(6 2
214 IMeshBuilder mb(spec);
215 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
219 if (out.vert_size() == 6 && out.face_size() == 6) {
220 const Vert *v0 = mb.arena.find_vert(mpq3(0, 0, 0));
221 const Vert *
v1 = mb.arena.find_vert(mpq3(4, 0, 0));
222 const Vert *
v2 = mb.arena.find_vert(mpq3(0, 4, 0));
223 const Vert *v3 = mb.arena.find_vert(mpq3(1, 0, 0));
224 const Vert *v4 = mb.arena.find_vert(mpq3(2, 0, 0));
225 const Vert *v5 = mb.arena.find_vert(mpq3(1, 1, 0));
226 EXPECT_TRUE(v0 !=
nullptr &&
v1 !=
nullptr &&
v2 !=
nullptr);
227 EXPECT_TRUE(v3 !=
nullptr && v4 !=
nullptr && v5 !=
nullptr);
228 if (v0 !=
nullptr &&
v1 !=
nullptr &&
v2 !=
nullptr && v3 !=
nullptr && v4 !=
nullptr &&
232 const Face *f0 = find_tri_with_verts(out, v4,
v1, v5);
233 const Face *f1 = find_tri_with_verts(out, v3, v4, v5);
234 const Face *f2 = find_tri_with_verts(out, v0, v3, v5);
235 const Face *f3 = find_tri_with_verts(out, v0, v5,
v2);
236 const Face *f4 = find_tri_with_verts(out, v5,
v1,
v2);
237 EXPECT_TRUE(f0 !=
nullptr && f1 !=
nullptr && f2 !=
nullptr && f3 !=
nullptr &&
241 EXPECT_EQ(count_tris_with_verts(out, v3, v4, v5), 2);
242 if (f0 !=
nullptr && f1 !=
nullptr && f2 !=
nullptr && f3 !=
nullptr && f4 !=
nullptr) {
244 EXPECT_TRUE(f1->orig == 0 || f1->orig == 1);
249 int e03 = find_edge_pos_in_tri(v0, v3, f2);
250 int e34 = find_edge_pos_in_tri(v3, v4, f1);
251 int e45 = find_edge_pos_in_tri(v4, v5, f1);
252 int e05 = find_edge_pos_in_tri(v0, v5, f3);
253 int e15 = find_edge_pos_in_tri(
v1, v5, f0);
254 EXPECT_TRUE(e03 != -1 && e34 != -1 && e45 != -1 && e05 != -1 && e15 != -1);
255 if (e03 != -1 && e34 != -1 && e45 != -1 && e05 != -1 && e15 != -1) {
257 EXPECT_TRUE(f1->edge_orig[e34] == 0 ||
258 f1->edge_orig[e34] == 1 * IMeshBuilder::MAX_FACE_LEN);
259 EXPECT_EQ(f1->edge_orig[e45], 1 * IMeshBuilder::MAX_FACE_LEN + 1);
266 write_obj_mesh(out,
"tritri");
270 TEST(mesh_intersect, TriTriReversed)
274 const char *spec = R
"(6 2
285 IMeshBuilder mb(spec);
286 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
290 if (out.vert_size() == 6 && out.face_size() == 6) {
291 const Vert *v0 = mb.arena.find_vert(mpq3(0, 0, 0));
292 const Vert *
v1 = mb.arena.find_vert(mpq3(4, 0, 0));
293 const Vert *
v2 = mb.arena.find_vert(mpq3(0, 4, 0));
294 const Vert *v3 = mb.arena.find_vert(mpq3(1, 0, 0));
295 const Vert *v4 = mb.arena.find_vert(mpq3(2, 0, 0));
296 const Vert *v5 = mb.arena.find_vert(mpq3(1, 1, 0));
297 EXPECT_TRUE(v0 !=
nullptr &&
v1 !=
nullptr &&
v2 !=
nullptr);
298 EXPECT_TRUE(v3 !=
nullptr && v4 !=
nullptr && v5 !=
nullptr);
299 if (v0 !=
nullptr &&
v1 !=
nullptr &&
v2 !=
nullptr && v3 !=
nullptr && v4 !=
nullptr &&
303 const Face *f0 = find_tri_with_verts(out, v4, v5,
v1);
304 const Face *f1 = find_tri_with_verts(out, v3, v5, v4);
305 const Face *f2 = find_tri_with_verts(out, v0, v5, v3);
306 const Face *f3 = find_tri_with_verts(out, v0,
v2, v5);
307 const Face *f4 = find_tri_with_verts(out, v5,
v2,
v1);
308 EXPECT_TRUE(f0 !=
nullptr && f1 !=
nullptr && f2 !=
nullptr && f3 !=
nullptr &&
312 EXPECT_EQ(count_tris_with_verts(out, v3, v5, v4), 2);
313 if (f0 !=
nullptr && f1 !=
nullptr && f2 !=
nullptr && f3 !=
nullptr && f4 !=
nullptr) {
315 EXPECT_TRUE(f1->orig == 0 || f1->orig == 1);
320 int e03 = find_edge_pos_in_tri(v0, v3, f2);
321 int e34 = find_edge_pos_in_tri(v3, v4, f1);
322 int e45 = find_edge_pos_in_tri(v4, v5, f1);
323 int e05 = find_edge_pos_in_tri(v0, v5, f3);
324 int e15 = find_edge_pos_in_tri(
v1, v5, f0);
325 EXPECT_TRUE(e03 != -1 && e34 != -1 && e45 != -1 && e05 != -1 && e15 != -1);
326 if (e03 != -1 && e34 != -1 && e45 != -1 && e05 != -1 && e15 != -1) {
328 EXPECT_TRUE(f1->edge_orig[e34] == 2 ||
329 f1->edge_orig[e34] == 1 * IMeshBuilder::MAX_FACE_LEN + 2);
330 EXPECT_EQ(f1->edge_orig[e45], 1 * IMeshBuilder::MAX_FACE_LEN + 1);
337 write_obj_mesh(out,
"tritrirev");
341 TEST(mesh_intersect, TwoTris)
343 Array<mpq3>
verts = {
344 mpq3(1, 1, 1), mpq3(1, 4, 1), mpq3(1, 1, 4),
345 mpq3(2, 2, 2), mpq3(-3, 3, 2), mpq3(-4, 1, 3),
346 mpq3(2, 2, 2), mpq3(-3, 3, 2), mpq3(0, 3, 5),
347 mpq3(2, 2, 2), mpq3(-3, 3, 2), mpq3(0, 3, 3),
348 mpq3(1, 0, 0), mpq3(2, 4, 1), mpq3(-3, 2, 2),
349 mpq3(0, 2, 1), mpq3(-2, 3, 3), mpq3(0, 1, 3),
350 mpq3(1.5, 2, 0.5), mpq3(-2, 3, 3), mpq3(0, 1, 3),
351 mpq3(1, 0, 0), mpq3(-2, 3, 3), mpq3(0, 1, 3),
352 mpq3(1, 0, 0), mpq3(-3, 2, 2), mpq3(0, 1, 3),
353 mpq3(1, 0, 0), mpq3(-1, 1, 1), mpq3(0, 1, 3),
354 mpq3(3, -1, -1), mpq3(-1, 1, 1), mpq3(0, 1, 3),
355 mpq3(0, 0.5, 0.5), mpq3(-1, 1, 1), mpq3(0, 1, 3),
356 mpq3(2, 1, 1), mpq3(3, 5, 2), mpq3(-2, 3, 3),
357 mpq3(2, 1, 1), mpq3(3, 5, 2), mpq3(-2, 3, 4),
358 mpq3(2, 2, 5), mpq3(-3, 3, 5), mpq3(0, 3, 10),
359 mpq3(0, 0, 0), mpq3(4, 4, 0), mpq3(-4, 2, 4),
360 mpq3(0, 1.5, 1), mpq3(1, 2.5, 1), mpq3(-1, 2, 2),
361 mpq3(3, 0, -2), mpq3(7, 4, -2), mpq3(-1, 2, 2),
362 mpq3(3, 0, -2), mpq3(3, 6, 2), mpq3(-1, 2, 2),
363 mpq3(7, 4, -2), mpq3(3, 6, 2), mpq3(-1, 2, 2),
364 mpq3(5, 2, -2), mpq3(1, 4, 2), mpq3(-3, 0, 2),
365 mpq3(2, 2, 0), mpq3(1, 4, 2), mpq3(-3, 0, 2),
366 mpq3(0, 0, 0), mpq3(4, 4, 0), mpq3(-3, 0, 2),
367 mpq3(0, 0, 0), mpq3(4, 4, 0), mpq3(-1, 2, 2),
368 mpq3(2, 2, 0), mpq3(4, 4, 0), mpq3(0, 3, 2),
369 mpq3(0, 0, 0), mpq3(-4, 2, 4), mpq3(4, 4, 0),
371 struct two_tri_test_spec {
377 Array<two_tri_test_spec> test_tris = Span<two_tri_test_spec>{
403 static int perms[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
405 const int do_only_test = -1;
406 for (
int test = 0; test < test_tris.size(); ++test) {
407 if (do_only_test >= 0 && test != do_only_test) {
410 int tri1_index = test_tris[test].t0;
411 int tri2_index = test_tris[test].t1;
412 int co1_i = 3 * tri1_index;
413 int co2_i = 3 * tri2_index;
418 std::cout <<
"\nTest " << test <<
": T" << tri1_index <<
" intersect T" << tri2_index
422 const bool do_all_perms =
true;
423 const int perm_limit = do_all_perms ? 3 : 1;
425 for (
int i = 0; i < perm_limit; ++i) {
426 for (
int j = 0; j < perm_limit; ++j) {
428 std::cout <<
"\nperms " << i <<
" " << j <<
"\n";
431 arena.reserve(2 * 3, 2);
432 Array<const Vert *> f0_verts(3);
433 Array<const Vert *> f1_verts(3);
434 for (
int k = 0; k < 3; ++k) {
435 f0_verts[k] = arena.add_or_find_vert(
verts[co1_i + perms[i][k]], k);
437 for (
int k = 0; k < 3; ++k) {
438 f1_verts[k] = arena.add_or_find_vert(
verts[co2_i + perms[i][k]], k + 3);
440 Face *f0 = arena.add_face(f0_verts, 0, {0, 1, 2});
441 Face *f1 = arena.add_face(f1_verts, 1, {3, 4, 5});
442 IMesh in_mesh({f0, f1});
443 IMesh out_mesh = trimesh_self_intersect(in_mesh, &arena);
444 out_mesh.populate_vert();
445 EXPECT_EQ(out_mesh.vert_size(), test_tris[test].nv_out);
446 EXPECT_EQ(out_mesh.face_size(), test_tris[test].nf_out);
447 bool constexpr dump_input =
true;
448 if (DO_OBJ && i == 0 && j == 0) {
451 write_obj_mesh(in_mesh, name);
454 write_obj_mesh(out_mesh, name);
461 TEST(mesh_intersect, OverlapCluster)
466 const char *spec = R
"(15 5
489 IMeshBuilder mb(spec);
490 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
495 write_obj_mesh(out,
"overlapcluster");
499 TEST(mesh_intersect, TriCornerCross1)
502 const char *spec = R
"(12 4
521 IMeshBuilder mb(spec);
522 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
527 write_obj_mesh(out,
"test_tc_1");
531 TEST(mesh_intersect, TriCornerCross2)
534 const char *spec = R
"(12 4
553 IMeshBuilder mb(spec);
554 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
559 write_obj_mesh(out,
"test_tc_2");
563 TEST(mesh_intersect, TriCornerCross3)
566 const char *spec = R
"(12 4
585 IMeshBuilder mb(spec);
586 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
591 write_obj_mesh(out,
"test_tc_3");
595 TEST(mesh_intersect, TetTet)
597 const char *spec = R
"(8 8
616 IMeshBuilder mb(spec);
617 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
623 const Vert *
v1 = mb.arena.find_vert(mpq3(2, 0, 0));
624 const Vert *v8 = mb.arena.find_vert(mpq3(0.5, 0.5, 1));
625 const Vert *v9 = mb.arena.find_vert(mpq3(1.5, 0.5, 1));
626 EXPECT_TRUE(
v1 && v8 && v9);
627 if (
v1 && v8 && v9) {
628 const Face *f = mb.arena.find_face({
v1, v8, v9});
629 EXPECT_NE(f,
nullptr);
632 int v1pos = f->vert[0] ==
v1 ? 0 : (f->vert[1] ==
v1 ? 1 : 2);
633 EXPECT_EQ(f->edge_orig[v1pos], NO_INDEX);
634 EXPECT_EQ(f->edge_orig[(v1pos + 1) % 3], NO_INDEX);
635 EXPECT_EQ(f->edge_orig[(v1pos + 2) % 3], 1001);
636 EXPECT_EQ(f->is_intersect[v1pos],
false);
637 EXPECT_EQ(f->is_intersect[(v1pos + 1) % 3],
true);
638 EXPECT_EQ(f->is_intersect[(v1pos + 2) % 3],
false);
642 write_obj_mesh(out,
"test_tc_3");
646 TEST(mesh_intersect, CubeCubeStep)
648 const char *spec = R
"(16 24
691 IMeshBuilder mb(spec);
692 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
697 write_obj_mesh(out,
"test_cubecubestep");
700 IMeshBuilder mb2(spec);
701 IMesh out2 = trimesh_nary_intersect(
702 mb2.imesh, 2, [](
int t) { return t < 12 ? 0 : 1; },
false, &mb2.arena);
703 out2.populate_vert();
707 write_obj_mesh(out2,
"test_cubecubestep_nary");
711 TEST(mesh_intersect, RectCross)
713 const char *spec = R
"(8 4
728 IMeshBuilder mb(spec);
729 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
734 write_obj_mesh(out,
"test_rectcross");
741 static void get_sphere_params(
742 int nrings,
int nsegs,
bool triangulate,
int *r_num_verts,
int *r_num_faces)
744 *r_num_verts = nsegs * (nrings - 1) + 2;
746 *r_num_faces = 2 * nsegs + 2 * nsegs * (nrings - 2);
749 *r_num_faces = nsegs * nrings;
753 static void fill_sphere_data(
int nrings,
758 MutableSpan<Face *> face,
765 get_sphere_params(nrings, nsegs, triangulate, &num_verts, &num_faces);
767 Array<const Vert *> vert(num_verts);
768 const bool nrings_even = (nrings % 2 == 0);
769 int half_nrings = nrings / 2;
770 const bool nsegs_even = (nsegs % 2) == 0;
771 const bool nsegs_four_divisible = (nsegs % 4 == 0);
772 int half_nsegs = nrings;
773 int quarter_nsegs = half_nsegs / 2;
775 double delta_theta =
M_PI / nrings;
778 auto vert_index_fn = [nrings, num_verts](
int seg,
int ring) {
780 return num_verts - 2;
782 if (ring == nrings) {
783 return num_verts - 1;
785 return seg * (nrings - 1) + (ring - 1);
787 auto face_index_fn = [nrings](
int seg,
int ring) {
return seg * nrings + ring; };
788 auto tri_index_fn = [nrings, nsegs](
int seg,
int ring,
int tri) {
792 if (ring < nrings - 1) {
793 return nsegs + 2 * (ring - 1) * nsegs + 2 * seg + tri;
795 return nsegs + 2 * (nrings - 2) * nsegs + seg;
797 Array<int> eid = {0, 0, 0, 0};
805 for (
int s = 0; s < nsegs; ++s) {
815 else if (nsegs_even && s == half_nsegs) {
820 else if (nsegs_four_divisible && s == quarter_nsegs) {
825 else if (nsegs_four_divisible && s == 3 * quarter_nsegs) {
834 for (
int r = 1;
r < nrings; ++
r) {
835 double theta =
r * delta_theta;
838 if (nrings_even &&
r == half_nrings) {
840 r_sin_theta = radius;
844 r_sin_theta = radius *
sin(theta);
845 r_cos_theta = radius *
cos(theta);
847 double x = r_sin_theta * cos_phi +
center[0];
848 double y = r_sin_theta * sin_phi +
center[1];
849 double z = r_cos_theta +
center[2];
850 const Vert *
v = arena->add_or_find_vert(mpq3(
x,
y,
z), vid++);
851 vert[vert_index_fn(s,
r)] =
v;
858 vert[vert_index_fn(0, 0)] = vtop;
859 vert[vert_index_fn(0, nrings)] = vbot;
860 for (
int s = 0; s < nsegs; ++s) {
861 int snext = (s + 1) % nsegs;
862 for (
int r = 0;
r < nrings; ++
r) {
864 int i0 = vert_index_fn(s,
r);
865 int i1 = vert_index_fn(s, rnext);
866 int i2 = vert_index_fn(snext, rnext);
867 int i3 = vert_index_fn(snext,
r);
871 f = arena->add_face({vert[i0], vert[
i1], vert[i2]}, fid++, eid);
873 else if (
r == nrings - 1) {
874 f = arena->add_face({vert[i0], vert[
i1], vert[i3]}, fid++, eid);
878 f = arena->add_face({vert[i0], vert[
i1], vert[i2]}, fid++, eid);
879 f2 = arena->add_face({vert[i2], vert[i3], vert[i0]}, fid++, eid);
882 f = arena->add_face({vert[i0], vert[
i1], vert[i2], vert[i3]}, fid++, eid);
886 int f_index = tri_index_fn(s,
r, 0);
888 if (
r != 0 &&
r != nrings - 1) {
889 int f_index2 = tri_index_fn(s,
r, 1);
894 int f_index = face_index_fn(s,
r);
901 static void spheresphere_test(
int nrings,
double y_offset,
bool use_self)
910 int nsegs = 2 * nrings;
911 int num_sphere_verts;
913 get_sphere_params(nrings, nsegs,
true, &num_sphere_verts, &num_sphere_tris);
914 Array<Face *> tris(2 * num_sphere_tris);
915 arena.reserve(6 * num_sphere_verts / 2, 8 * num_sphere_tris);
916 double3 center1(0.0, 0.0, 0.0);
917 fill_sphere_data(nrings,
922 MutableSpan<Face *>(tris.begin(), num_sphere_tris),
926 double3 center2(0.0, y_offset, 0.0);
927 fill_sphere_data(nrings,
932 MutableSpan<Face *>(tris.begin() + num_sphere_tris, num_sphere_tris),
941 out = trimesh_self_intersect(
mesh, &arena);
944 int nf = num_sphere_tris;
945 out = trimesh_nary_intersect(
946 mesh, 2, [nf](
int t) {
return t < nf ? 0 : 1; },
false, &arena);
949 std::cout <<
"Create time: " << time_create - time_start <<
"\n";
950 std::cout <<
"Intersect time: " << time_intersect - time_create <<
"\n";
951 std::cout <<
"Total time: " << time_intersect - time_start <<
"\n";
953 write_obj_mesh(out,
"spheresphere");
958 static void get_grid_params(
959 int x_subdiv,
int y_subdiv,
bool triangulate,
int *r_num_verts,
int *r_num_faces)
961 *r_num_verts = x_subdiv * y_subdiv;
963 *r_num_faces = 2 * (x_subdiv - 1) * (y_subdiv - 1);
966 *r_num_faces = (x_subdiv - 1) * (y_subdiv - 1);
970 static void fill_grid_data(
int x_subdiv,
976 MutableSpan<Face *> face,
981 if (x_subdiv <= 1 || y_subdiv <= 1) {
986 get_grid_params(x_subdiv, y_subdiv, triangulate, &num_verts, &num_faces);
988 Array<const Vert *> vert(num_verts);
989 auto vert_index_fn = [x_subdiv](
int ix,
int iy) {
return iy * x_subdiv + ix; };
990 auto face_index_fn = [x_subdiv](
int ix,
int iy) {
return iy * (x_subdiv - 1) + ix; };
991 auto tri_index_fn = [x_subdiv](
int ix,
int iy,
int tri) {
992 return 2 * iy * (x_subdiv - 1) + 2 * ix + tri;
994 Array<int> eid = {0, 0, 0, 0};
995 double r =
size / 2.0;
996 double delta_x =
size / (x_subdiv - 1);
997 double delta_y =
size / (y_subdiv - 1);
999 double cos_rot =
cosf(rot_deg *
M_PI / 180.0);
1000 double sin_rot =
sinf(rot_deg *
M_PI / 180.0);
1001 for (
int iy = 0; iy < y_subdiv; ++iy) {
1002 double yy = iy * delta_y -
r;
1003 for (
int ix = 0; ix < x_subdiv; ++ix) {
1004 double xx = ix * delta_x -
r;
1008 if (rot_deg != 0.0) {
1009 x =
center[0] + xx * cos_rot - yy * sin_rot;
1010 y =
center[1] + xx * sin_rot + yy * cos_rot;
1012 const Vert *
v = arena->add_or_find_vert(mpq3(
x,
y,
z), vid++);
1013 vert[vert_index_fn(ix, iy)] =
v;
1016 int fid = fid_start;
1017 for (
int iy = 0; iy < y_subdiv - 1; ++iy) {
1018 for (
int ix = 0; ix < x_subdiv - 1; ++ix) {
1019 int i0 = vert_index_fn(ix, iy);
1020 int i1 = vert_index_fn(ix, iy + 1);
1021 int i2 = vert_index_fn(ix + 1, iy + 1);
1022 int i3 = vert_index_fn(ix + 1, iy);
1024 Face *f = arena->add_face({vert[i0], vert[
i1], vert[i2]}, fid++, eid);
1025 Face *f2 = arena->add_face({vert[i2], vert[i3], vert[i0]}, fid++, eid);
1026 face[tri_index_fn(ix, iy, 0)] = f;
1027 face[tri_index_fn(ix, iy, 1)] = f2;
1030 Face *f = arena->add_face({vert[i0], vert[
i1], vert[i2], vert[i3]}, fid++, eid);
1031 face[face_index_fn(ix, iy)] = f;
1037 static void spheregrid_test(
int nrings,
int grid_level,
double z_offset,
bool use_self)
1044 if (nrings < 2 || grid_level < 1) {
1050 int num_sphere_verts;
1051 int num_sphere_tris;
1052 int nsegs = 2 * nrings;
1055 int subdivs = 1 << grid_level;
1056 get_sphere_params(nrings, nsegs,
true, &num_sphere_verts, &num_sphere_tris);
1057 get_grid_params(subdivs, subdivs,
true, &num_grid_verts, &num_grid_tris);
1058 Array<Face *> tris(num_sphere_tris + num_grid_tris);
1059 arena.reserve(3 * (num_sphere_verts + num_grid_verts) / 2,
1060 4 * (num_sphere_tris + num_grid_tris));
1061 double3
center(0.0, 0.0, z_offset);
1062 fill_sphere_data(nrings,
1067 MutableSpan<Face *>(tris.begin(), num_sphere_tris),
1071 fill_grid_data(subdivs,
1077 MutableSpan<Face *>(tris.begin() + num_sphere_tris, num_grid_tris),
1086 out = trimesh_self_intersect(
mesh, &arena);
1089 int nf = num_sphere_tris;
1090 out = trimesh_nary_intersect(
1091 mesh, 2, [nf](
int t) {
return t < nf ? 0 : 1; },
false, &arena);
1094 std::cout <<
"Create time: " << time_create - time_start <<
"\n";
1095 std::cout <<
"Intersect time: " << time_intersect - time_create <<
"\n";
1096 std::cout <<
"Total time: " << time_intersect - time_start <<
"\n";
1098 write_obj_mesh(out,
"spheregrid");
1103 static void gridgrid_test(
int x_level_1,
1117 int x_subdivs_1 = 1 << x_level_1;
1118 int y_subdivs_1 = 1 << y_level_1;
1119 int x_subdivs_2 = 1 << x_level_2;
1120 int y_subdivs_2 = 1 << y_level_2;
1121 int num_grid_verts_1;
1122 int num_grid_verts_2;
1123 int num_grid_tris_1;
1124 int num_grid_tris_2;
1125 get_grid_params(x_subdivs_1, y_subdivs_1,
true, &num_grid_verts_1, &num_grid_tris_1);
1126 get_grid_params(x_subdivs_2, y_subdivs_2,
true, &num_grid_verts_2, &num_grid_tris_2);
1127 Array<Face *> tris(num_grid_tris_1 + num_grid_tris_2);
1128 arena.reserve(3 * (num_grid_verts_1 + num_grid_verts_2) / 2,
1129 4 * (num_grid_tris_1 + num_grid_tris_2));
1130 fill_grid_data(x_subdivs_1,
1136 MutableSpan<Face *>(tris.begin(), num_grid_tris_1),
1140 fill_grid_data(x_subdivs_2,
1144 double3(x_off, y_off, 0),
1146 MutableSpan<Face *>(tris.begin() + num_grid_tris_1, num_grid_tris_2),
1155 out = trimesh_self_intersect(
mesh, &arena);
1158 int nf = num_grid_tris_1;
1159 out = trimesh_nary_intersect(
1160 mesh, 2, [nf](
int t) {
return t < nf ? 0 : 1; },
false, &arena);
1163 std::cout <<
"Create time: " << time_create - time_start <<
"\n";
1164 std::cout <<
"Intersect time: " << time_intersect - time_create <<
"\n";
1165 std::cout <<
"Total time: " << time_intersect - time_start <<
"\n";
1167 write_obj_mesh(out,
"gridgrid");
1172 TEST(mesh_intersect_perf, SphereSphere)
1174 spheresphere_test(512, 0.5,
false);
1177 TEST(mesh_intersect_perf, SphereSphereSelf)
1179 spheresphere_test(64, 0.5,
true);
1182 TEST(mesh_intersect_perf, SphereGrid)
1184 spheregrid_test(512, 4, 0.1,
false);
1187 TEST(mesh_intersect_perf, SphereGridSelf)
1189 spheregrid_test(64, 4, 0.1,
true);
1192 TEST(mesh_intersect_perf, GridGrid)
1194 gridgrid_test(8, 2, 4, 2, 0.1, 0.1, 0.0,
false);
1197 TEST(mesh_intersect_perf, GridGridTilt)
1199 gridgrid_test(8, 2, 4, 2, 0.0, 0.0, 1.0,
false);
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
void BLI_task_scheduler_init(void)
void BLI_task_scheduler_exit(void)
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Platform independent time functions.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
std::string to_string(const T &n)
double PIL_check_seconds_timer(void)