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);
53 IMeshBuilder(
const char *spec)
55 std::istringstream ss(spec);
58 std::istringstream hdrss(line);
61 if (nv == 0 || nf == 0) {
64 arena.reserve(nv, nf);
65 Vector<const Vert *>
verts;
69 while (v_index < nv && spec_ok && getline(ss, line)) {
70 std::istringstream iss(line);
74 iss >> p0 >> p1 >> p2;
75 spec_ok = !iss.fail();
77 verts.append(arena.add_or_find_vert(mpq3(p0, p1, p2), v_index));
85 while (f_index < nf && spec_ok && getline(ss, line)) {
86 std::istringstream fss(line);
87 Vector<const Vert *> face_verts;
88 Vector<int> edge_orig;
90 while (spec_ok && fss >> v_index) {
91 if (v_index < 0 || v_index >= nv) {
95 face_verts.append(
verts[v_index]);
96 edge_orig.append(edge_index(f_index, fpos));
103 Face *facep = arena.add_face(face_verts, f_index, edge_orig);
112 std::cout <<
"Bad spec: " << spec;
115 imesh = IMesh(
faces);
122 static const Face *find_tri_with_verts(
const IMesh &
mesh,
127 Face f_arg({v0,
v1,
v2}, 0, NO_INDEX);
128 for (
const Face *f :
mesh.faces()) {
129 if (f->cyclic_equal(f_arg)) {
137 static int count_tris_with_verts(
const IMesh &
mesh,
const Vert *v0,
const Vert *
v1,
const Vert *
v2)
139 Face f_arg({v0,
v1,
v2}, 0, NO_INDEX);
141 for (
const Face *f :
mesh.faces()) {
142 if (f->cyclic_equal(f_arg)) {
151 static int find_edge_pos_in_tri(
const Vert *v0,
const Vert *
v1,
const Face *f)
153 for (
int pos : f->index_range()) {
154 int nextpos = f->next_pos(
pos);
155 if (((*f)[
pos] == v0 && (*f)[nextpos] ==
v1) || ((*f)[
pos] ==
v1 && (*f)[nextpos] == v0)) {
156 return static_cast<int>(
pos);
162 # if DO_REGULAR_TESTS
165 Vector<const Vert *>
verts;
166 Vector<Face *>
faces;
169 verts.append(arena.add_or_find_vert(mpq3(0, 0, 1), 0));
170 verts.append(arena.add_or_find_vert(mpq3(1, 0, 1), 1));
171 verts.append(arena.add_or_find_vert(mpq3(0.5, 1, 1), 2));
172 faces.append(arena.add_face(
verts, 0, {10, 11, 12}));
176 EXPECT_TRUE(f->is_tri());
179 TEST(mesh_intersect, TriangulateTri)
181 const char *spec = R
"(3 1
188 IMeshBuilder mb(spec);
189 IMesh im_tri = triangulate_polymesh(mb.imesh, &mb.arena);
193 TEST(mesh_intersect, TriangulateQuad)
195 const char *spec = R
"(4 1
203 IMeshBuilder mb(spec);
204 IMesh im_tri = triangulate_polymesh(mb.imesh, &mb.arena);
208 TEST(mesh_intersect, TriangulatePentagon)
210 const char *spec = R
"(5 1
219 IMeshBuilder mb(spec);
220 IMesh im_tri = triangulate_polymesh(mb.imesh, &mb.arena);
223 write_obj_mesh(im_tri,
"pentagon");
227 TEST(mesh_intersect, TriangulateTwoFaces)
229 const char *spec = R
"(7 2
230 461/250 -343/125 103/1000
231 -3/40 -453/200 -97/500
232 237/100 -321/200 -727/500
233 451/1000 -563/500 -1751/1000
234 12/125 -2297/1000 -181/1000
235 12/125 -411/200 -493/1000
236 1959/1000 -2297/1000 -493/1000
241 IMeshBuilder mb(spec);
242 IMesh im_tri = triangulate_polymesh(mb.imesh, &mb.arena);
245 write_obj_mesh(im_tri,
"twofaces");
249 TEST(mesh_intersect, OneTri)
251 const char *spec = R
"(3 1
258 IMeshBuilder mb(spec);
259 IMesh imesh = trimesh_self_intersect(mb.imesh, &mb.arena);
260 imesh.populate_vert();
263 const Face &f_in = *mb.imesh.face(0);
264 const Face &f_out = *imesh.face(0);
266 for (
int i = 0; i < 3; ++i) {
268 EXPECT_EQ(f_in.edge_orig[i], f_out.edge_orig[i]);
272 TEST(mesh_intersect, TriTri)
274 const char *spec = R
"(6 2
286 IMeshBuilder mb(spec);
287 IMesh
out = trimesh_self_intersect(mb.imesh, &mb.arena);
291 if (
out.vert_size() == 6 &&
out.face_size() == 6) {
292 const Vert *v0 = mb.arena.find_vert(mpq3(0, 0, 0));
293 const Vert *
v1 = mb.arena.find_vert(mpq3(4, 0, 0));
294 const Vert *
v2 = mb.arena.find_vert(mpq3(0, 4, 0));
295 const Vert *v3 = mb.arena.find_vert(mpq3(1, 0, 0));
296 const Vert *v4 = mb.arena.find_vert(mpq3(2, 0, 0));
297 const Vert *v5 = mb.arena.find_vert(mpq3(1, 1, 0));
298 EXPECT_TRUE(v0 !=
nullptr &&
v1 !=
nullptr &&
v2 !=
nullptr);
299 EXPECT_TRUE(v3 !=
nullptr && v4 !=
nullptr && v5 !=
nullptr);
300 if (v0 !=
nullptr &&
v1 !=
nullptr &&
v2 !=
nullptr && v3 !=
nullptr && v4 !=
nullptr &&
304 const Face *f0 = find_tri_with_verts(
out, v4,
v1, v5);
305 const Face *f1 = find_tri_with_verts(
out, v3, v4, v5);
306 const Face *f2 = find_tri_with_verts(
out, v0, v3, v5);
307 const Face *f3 = find_tri_with_verts(
out, v0, v5,
v2);
308 const Face *f4 = find_tri_with_verts(
out, v5,
v1,
v2);
309 EXPECT_TRUE(f0 !=
nullptr && f1 !=
nullptr && f2 !=
nullptr && f3 !=
nullptr &&
314 if (f0 !=
nullptr && f1 !=
nullptr && f2 !=
nullptr && f3 !=
nullptr && f4 !=
nullptr) {
316 EXPECT_TRUE(f1->orig == 0 || f1->orig == 1);
321 int e03 = find_edge_pos_in_tri(v0, v3, f2);
322 int e34 = find_edge_pos_in_tri(v3, v4, f1);
323 int e45 = find_edge_pos_in_tri(v4, v5, f1);
324 int e05 = find_edge_pos_in_tri(v0, v5, f3);
325 int e15 = find_edge_pos_in_tri(
v1, v5, f0);
326 EXPECT_TRUE(e03 != -1 && e34 != -1 && e45 != -1 && e05 != -1 && e15 != -1);
327 if (e03 != -1 && e34 != -1 && e45 != -1 && e05 != -1 && e15 != -1) {
329 EXPECT_TRUE(f1->edge_orig[e34] == 0 ||
330 f1->edge_orig[e34] == 1 * IMeshBuilder::MAX_FACE_LEN);
331 EXPECT_EQ(f1->edge_orig[e45], 1 * IMeshBuilder::MAX_FACE_LEN + 1);
338 write_obj_mesh(
out,
"tritri");
342 TEST(mesh_intersect, TriTriReversed)
346 const char *spec = R
"(6 2
357 IMeshBuilder mb(spec);
358 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
362 if (
out.vert_size() == 6 &&
out.face_size() == 6) {
363 const Vert *v0 = mb.arena.find_vert(mpq3(0, 0, 0));
364 const Vert *
v1 = mb.arena.find_vert(mpq3(4, 0, 0));
365 const Vert *
v2 = mb.arena.find_vert(mpq3(0, 4, 0));
366 const Vert *v3 = mb.arena.find_vert(mpq3(1, 0, 0));
367 const Vert *v4 = mb.arena.find_vert(mpq3(2, 0, 0));
368 const Vert *v5 = mb.arena.find_vert(mpq3(1, 1, 0));
369 EXPECT_TRUE(v0 !=
nullptr &&
v1 !=
nullptr &&
v2 !=
nullptr);
370 EXPECT_TRUE(v3 !=
nullptr && v4 !=
nullptr && v5 !=
nullptr);
371 if (v0 !=
nullptr &&
v1 !=
nullptr &&
v2 !=
nullptr && v3 !=
nullptr && v4 !=
nullptr &&
375 const Face *f0 = find_tri_with_verts(
out, v4, v5,
v1);
376 const Face *f1 = find_tri_with_verts(
out, v3, v5, v4);
377 const Face *f2 = find_tri_with_verts(
out, v0, v5, v3);
378 const Face *f3 = find_tri_with_verts(
out, v0,
v2, v5);
379 const Face *f4 = find_tri_with_verts(
out, v5,
v2,
v1);
380 EXPECT_TRUE(f0 !=
nullptr && f1 !=
nullptr && f2 !=
nullptr && f3 !=
nullptr &&
385 if (f0 !=
nullptr && f1 !=
nullptr && f2 !=
nullptr && f3 !=
nullptr && f4 !=
nullptr) {
387 EXPECT_TRUE(f1->orig == 0 || f1->orig == 1);
392 int e03 = find_edge_pos_in_tri(v0, v3, f2);
393 int e34 = find_edge_pos_in_tri(v3, v4, f1);
394 int e45 = find_edge_pos_in_tri(v4, v5, f1);
395 int e05 = find_edge_pos_in_tri(v0, v5, f3);
396 int e15 = find_edge_pos_in_tri(
v1, v5, f0);
397 EXPECT_TRUE(e03 != -1 && e34 != -1 && e45 != -1 && e05 != -1 && e15 != -1);
398 if (e03 != -1 && e34 != -1 && e45 != -1 && e05 != -1 && e15 != -1) {
400 EXPECT_TRUE(f1->edge_orig[e34] == 2 ||
401 f1->edge_orig[e34] == 1 * IMeshBuilder::MAX_FACE_LEN + 2);
402 EXPECT_EQ(f1->edge_orig[e45], 1 * IMeshBuilder::MAX_FACE_LEN + 1);
409 write_obj_mesh(
out,
"tritrirev");
413 TEST(mesh_intersect, TwoTris)
415 Array<mpq3>
verts = {
416 mpq3(1, 1, 1), mpq3(1, 4, 1), mpq3(1, 1, 4),
417 mpq3(2, 2, 2), mpq3(-3, 3, 2), mpq3(-4, 1, 3),
418 mpq3(2, 2, 2), mpq3(-3, 3, 2), mpq3(0, 3, 5),
419 mpq3(2, 2, 2), mpq3(-3, 3, 2), mpq3(0, 3, 3),
420 mpq3(1, 0, 0), mpq3(2, 4, 1), mpq3(-3, 2, 2),
421 mpq3(0, 2, 1), mpq3(-2, 3, 3), mpq3(0, 1, 3),
422 mpq3(1.5, 2, 0.5), mpq3(-2, 3, 3), mpq3(0, 1, 3),
423 mpq3(1, 0, 0), mpq3(-2, 3, 3), mpq3(0, 1, 3),
424 mpq3(1, 0, 0), mpq3(-3, 2, 2), mpq3(0, 1, 3),
425 mpq3(1, 0, 0), mpq3(-1, 1, 1), mpq3(0, 1, 3),
426 mpq3(3, -1, -1), mpq3(-1, 1, 1), mpq3(0, 1, 3),
427 mpq3(0, 0.5, 0.5), mpq3(-1, 1, 1), mpq3(0, 1, 3),
428 mpq3(2, 1, 1), mpq3(3, 5, 2), mpq3(-2, 3, 3),
429 mpq3(2, 1, 1), mpq3(3, 5, 2), mpq3(-2, 3, 4),
430 mpq3(2, 2, 5), mpq3(-3, 3, 5), mpq3(0, 3, 10),
431 mpq3(0, 0, 0), mpq3(4, 4, 0), mpq3(-4, 2, 4),
432 mpq3(0, 1.5, 1), mpq3(1, 2.5, 1), mpq3(-1, 2, 2),
433 mpq3(3, 0, -2), mpq3(7, 4, -2), mpq3(-1, 2, 2),
434 mpq3(3, 0, -2), mpq3(3, 6, 2), mpq3(-1, 2, 2),
435 mpq3(7, 4, -2), mpq3(3, 6, 2), mpq3(-1, 2, 2),
436 mpq3(5, 2, -2), mpq3(1, 4, 2), mpq3(-3, 0, 2),
437 mpq3(2, 2, 0), mpq3(1, 4, 2), mpq3(-3, 0, 2),
438 mpq3(0, 0, 0), mpq3(4, 4, 0), mpq3(-3, 0, 2),
439 mpq3(0, 0, 0), mpq3(4, 4, 0), mpq3(-1, 2, 2),
440 mpq3(2, 2, 0), mpq3(4, 4, 0), mpq3(0, 3, 2),
441 mpq3(0, 0, 0), mpq3(-4, 2, 4), mpq3(4, 4, 0),
443 struct two_tri_test_spec {
449 Array<two_tri_test_spec> test_tris = Span<two_tri_test_spec>{
475 static int perms[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
477 const int do_only_test = -1;
478 for (
int test = 0; test < test_tris.size(); ++test) {
479 if (do_only_test >= 0 && test != do_only_test) {
482 int tri1_index = test_tris[test].t0;
483 int tri2_index = test_tris[test].t1;
484 int co1_i = 3 * tri1_index;
485 int co2_i = 3 * tri2_index;
490 std::cout <<
"\nTest " << test <<
": T" << tri1_index <<
" intersect T" << tri2_index
494 const bool do_all_perms =
true;
495 const int perm_limit = do_all_perms ? 3 : 1;
497 for (
int i = 0; i < perm_limit; ++i) {
498 for (
int j = 0; j < perm_limit; ++j) {
500 std::cout <<
"\nperms " << i <<
" " << j <<
"\n";
503 arena.reserve(2 * 3, 2);
504 Array<const Vert *> f0_verts(3);
505 Array<const Vert *> f1_verts(3);
506 for (
int k = 0; k < 3; ++k) {
507 f0_verts[k] = arena.add_or_find_vert(
verts[co1_i + perms[i][k]], k);
509 for (
int k = 0; k < 3; ++k) {
510 f1_verts[k] = arena.add_or_find_vert(
verts[co2_i + perms[i][k]], k + 3);
512 Face *f0 = arena.add_face(f0_verts, 0, {0, 1, 2});
513 Face *f1 = arena.add_face(f1_verts, 1, {3, 4, 5});
514 IMesh in_mesh({f0, f1});
515 IMesh out_mesh = trimesh_self_intersect(in_mesh, &arena);
516 out_mesh.populate_vert();
517 EXPECT_EQ(out_mesh.vert_size(), test_tris[test].nv_out);
518 EXPECT_EQ(out_mesh.face_size(), test_tris[test].nf_out);
519 bool constexpr dump_input =
true;
520 if (DO_OBJ && i == 0 && j == 0) {
523 write_obj_mesh(in_mesh, name);
526 write_obj_mesh(out_mesh, name);
533 TEST(mesh_intersect, OverlapCluster)
538 const char *spec = R
"(15 5
561 IMeshBuilder mb(spec);
562 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
567 write_obj_mesh(
out,
"overlapcluster");
571 TEST(mesh_intersect, TriCornerCross1)
574 const char *spec = R
"(12 4
593 IMeshBuilder mb(spec);
594 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
599 write_obj_mesh(
out,
"test_tc_1");
603 TEST(mesh_intersect, TriCornerCross2)
606 const char *spec = R
"(12 4
625 IMeshBuilder mb(spec);
626 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
631 write_obj_mesh(
out,
"test_tc_2");
635 TEST(mesh_intersect, TriCornerCross3)
638 const char *spec = R
"(12 4
657 IMeshBuilder mb(spec);
658 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
663 write_obj_mesh(
out,
"test_tc_3");
667 TEST(mesh_intersect, TetTet)
669 const char *spec = R
"(8 8
688 IMeshBuilder mb(spec);
689 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
695 const Vert *
v1 = mb.arena.find_vert(mpq3(2, 0, 0));
696 const Vert *v8 = mb.arena.find_vert(mpq3(0.5, 0.5, 1));
697 const Vert *v9 = mb.arena.find_vert(mpq3(1.5, 0.5, 1));
698 EXPECT_TRUE(
v1 && v8 && v9);
699 if (
v1 && v8 && v9) {
700 const Face *f = mb.arena.find_face({
v1, v8, v9});
701 EXPECT_NE(f,
nullptr);
704 int v1pos = f->vert[0] ==
v1 ? 0 : (f->vert[1] ==
v1 ? 1 : 2);
705 EXPECT_EQ(f->edge_orig[v1pos], NO_INDEX);
706 EXPECT_EQ(f->edge_orig[(v1pos + 1) % 3], NO_INDEX);
707 EXPECT_EQ(f->edge_orig[(v1pos + 2) % 3], 1001);
708 EXPECT_EQ(f->is_intersect[v1pos],
false);
709 EXPECT_EQ(f->is_intersect[(v1pos + 1) % 3],
true);
710 EXPECT_EQ(f->is_intersect[(v1pos + 2) % 3],
false);
714 write_obj_mesh(
out,
"test_tc_3");
718 TEST(mesh_intersect, CubeCubeStep)
720 const char *spec = R
"(16 24
763 IMeshBuilder mb(spec);
764 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
769 write_obj_mesh(
out,
"test_cubecubestep");
772 IMeshBuilder mb2(spec);
773 IMesh out2 = trimesh_nary_intersect(
774 mb2.imesh, 2, [](
int t) { return t < 12 ? 0 : 1; },
false, &mb2.arena);
775 out2.populate_vert();
779 write_obj_mesh(out2,
"test_cubecubestep_nary");
783 TEST(mesh_intersect, RectCross)
785 const char *spec = R
"(8 4
800 IMeshBuilder mb(spec);
801 IMesh out = trimesh_self_intersect(mb.imesh, &mb.arena);
806 write_obj_mesh(
out,
"test_rectcross");
813 static void get_sphere_params(
814 int nrings,
int nsegs,
bool triangulate,
int *r_verts_num,
int *r_faces_num)
816 *r_verts_num = nsegs * (nrings - 1) + 2;
818 *r_faces_num = 2 * nsegs + 2 * nsegs * (nrings - 2);
821 *r_faces_num = nsegs * nrings;
825 static void fill_sphere_data(
int nrings,
830 MutableSpan<Face *> face,
837 get_sphere_params(nrings, nsegs, triangulate, &verts_num, &faces_num);
839 Array<const Vert *> vert(verts_num);
840 const bool nrings_even = (nrings % 2 == 0);
841 int half_nrings = nrings / 2;
842 const bool nsegs_even = (nsegs % 2) == 0;
843 const bool nsegs_four_divisible = (nsegs % 4 == 0);
844 int half_nsegs = nrings;
845 int quarter_nsegs = half_nsegs / 2;
847 double delta_theta =
M_PI / nrings;
850 auto vert_index_fn = [nrings, verts_num](
int seg,
int ring) {
852 return verts_num - 2;
854 if (ring == nrings) {
855 return verts_num - 1;
857 return seg * (nrings - 1) + (ring - 1);
859 auto face_index_fn = [nrings](
int seg,
int ring) {
return seg * nrings + ring; };
860 auto tri_index_fn = [nrings, nsegs](
int seg,
int ring,
int tri) {
864 if (ring < nrings - 1) {
865 return nsegs + 2 * (ring - 1) * nsegs + 2 * seg + tri;
867 return nsegs + 2 * (nrings - 2) * nsegs + seg;
869 Array<int> eid = {0, 0, 0, 0};
877 for (
int s = 0; s < nsegs; ++s) {
887 else if (nsegs_even && s == half_nsegs) {
892 else if (nsegs_four_divisible && s == quarter_nsegs) {
897 else if (nsegs_four_divisible && s == 3 * quarter_nsegs) {
906 for (
int r = 1;
r < nrings; ++
r) {
907 double theta =
r * delta_theta;
910 if (nrings_even &&
r == half_nrings) {
912 r_sin_theta = radius;
916 r_sin_theta = radius *
sin(theta);
917 r_cos_theta = radius *
cos(theta);
919 double x = r_sin_theta * cos_phi +
center[0];
920 double y = r_sin_theta * sin_phi +
center[1];
921 double z = r_cos_theta +
center[2];
922 const Vert *
v = arena->add_or_find_vert(mpq3(
x,
y,
z), vid++);
923 vert[vert_index_fn(s,
r)] =
v;
930 vert[vert_index_fn(0, 0)] = vtop;
931 vert[vert_index_fn(0, nrings)] = vbot;
932 for (
int s = 0; s < nsegs; ++s) {
933 int snext = (s + 1) % nsegs;
934 for (
int r = 0;
r < nrings; ++
r) {
936 int i0 = vert_index_fn(s,
r);
937 int i1 = vert_index_fn(s, rnext);
938 int i2 = vert_index_fn(snext, rnext);
939 int i3 = vert_index_fn(snext,
r);
943 f = arena->add_face({vert[i0], vert[
i1], vert[i2]}, fid++, eid);
945 else if (
r == nrings - 1) {
946 f = arena->add_face({vert[i0], vert[
i1], vert[i3]}, fid++, eid);
950 f = arena->add_face({vert[i0], vert[
i1], vert[i2]}, fid++, eid);
951 f2 = arena->add_face({vert[i2], vert[i3], vert[i0]}, fid++, eid);
954 f = arena->add_face({vert[i0], vert[
i1], vert[i2], vert[i3]}, fid++, eid);
958 int f_index = tri_index_fn(s,
r, 0);
960 if (
r != 0 &&
r != nrings - 1) {
961 int f_index2 = tri_index_fn(s,
r, 1);
966 int f_index = face_index_fn(s,
r);
973 static void spheresphere_test(
int nrings,
double y_offset,
bool use_self)
982 int nsegs = 2 * nrings;
983 int sphere_verts_num;
985 get_sphere_params(nrings, nsegs,
true, &sphere_verts_num, &sphere_tris_num);
986 Array<Face *> tris(2 * sphere_tris_num);
987 arena.reserve(6 * sphere_verts_num / 2, 8 * sphere_tris_num);
988 double3 center1(0.0, 0.0, 0.0);
989 fill_sphere_data(nrings,
994 MutableSpan<Face *>(tris.begin(), sphere_tris_num),
998 double3 center2(0.0, y_offset, 0.0);
999 fill_sphere_data(nrings,
1004 MutableSpan<Face *>(tris.begin() + sphere_tris_num, sphere_tris_num),
1013 out = trimesh_self_intersect(
mesh, &arena);
1016 int nf = sphere_tris_num;
1017 out = trimesh_nary_intersect(
1018 mesh, 2, [nf](
int t) {
return t < nf ? 0 : 1; },
false, &arena);
1021 std::cout <<
"Create time: " << time_create - time_start <<
"\n";
1022 std::cout <<
"Intersect time: " << time_intersect - time_create <<
"\n";
1023 std::cout <<
"Total time: " << time_intersect - time_start <<
"\n";
1025 write_obj_mesh(
out,
"spheresphere");
1030 static void get_grid_params(
1031 int x_subdiv,
int y_subdiv,
bool triangulate,
int *r_verts_num,
int *r_faces_num)
1033 *r_verts_num = x_subdiv * y_subdiv;
1035 *r_faces_num = 2 * (x_subdiv - 1) * (y_subdiv - 1);
1038 *r_faces_num = (x_subdiv - 1) * (y_subdiv - 1);
1042 static void fill_grid_data(
int x_subdiv,
1048 MutableSpan<Face *> face,
1053 if (x_subdiv <= 1 || y_subdiv <= 1) {
1058 get_grid_params(x_subdiv, y_subdiv, triangulate, &verts_num, &faces_num);
1060 Array<const Vert *> vert(verts_num);
1061 auto vert_index_fn = [x_subdiv](
int ix,
int iy) {
return iy * x_subdiv + ix; };
1062 auto face_index_fn = [x_subdiv](
int ix,
int iy) {
return iy * (x_subdiv - 1) + ix; };
1063 auto tri_index_fn = [x_subdiv](
int ix,
int iy,
int tri) {
1064 return 2 * iy * (x_subdiv - 1) + 2 * ix + tri;
1066 Array<int> eid = {0, 0, 0, 0};
1067 double r =
size / 2.0;
1068 double delta_x =
size / (x_subdiv - 1);
1069 double delta_y =
size / (y_subdiv - 1);
1070 int vid = vid_start;
1071 double cos_rot =
cosf(rot_deg *
M_PI / 180.0);
1072 double sin_rot =
sinf(rot_deg *
M_PI / 180.0);
1073 for (
int iy = 0; iy < y_subdiv; ++iy) {
1074 double yy = iy * delta_y -
r;
1075 for (
int ix = 0; ix < x_subdiv; ++ix) {
1076 double xx = ix * delta_x -
r;
1080 if (rot_deg != 0.0) {
1081 x =
center[0] + xx * cos_rot - yy * sin_rot;
1082 y =
center[1] + xx * sin_rot + yy * cos_rot;
1084 const Vert *
v = arena->add_or_find_vert(mpq3(
x,
y,
z), vid++);
1085 vert[vert_index_fn(ix, iy)] =
v;
1088 int fid = fid_start;
1089 for (
int iy = 0; iy < y_subdiv - 1; ++iy) {
1090 for (
int ix = 0; ix < x_subdiv - 1; ++ix) {
1091 int i0 = vert_index_fn(ix, iy);
1092 int i1 = vert_index_fn(ix, iy + 1);
1093 int i2 = vert_index_fn(ix + 1, iy + 1);
1094 int i3 = vert_index_fn(ix + 1, iy);
1096 Face *f = arena->add_face({vert[i0], vert[
i1], vert[i2]}, fid++, eid);
1097 Face *f2 = arena->add_face({vert[i2], vert[i3], vert[i0]}, fid++, eid);
1098 face[tri_index_fn(ix, iy, 0)] = f;
1099 face[tri_index_fn(ix, iy, 1)] = f2;
1102 Face *f = arena->add_face({vert[i0], vert[
i1], vert[i2], vert[i3]}, fid++, eid);
1103 face[face_index_fn(ix, iy)] = f;
1109 static void spheregrid_test(
int nrings,
int grid_level,
double z_offset,
bool use_self)
1116 if (nrings < 2 || grid_level < 1) {
1122 int sphere_verts_num;
1123 int sphere_tris_num;
1124 int nsegs = 2 * nrings;
1127 int subdivs = 1 << grid_level;
1128 get_sphere_params(nrings, nsegs,
true, &sphere_verts_num, &sphere_tris_num);
1129 get_grid_params(subdivs, subdivs,
true, &grid_verts_num, &grid_tris_num);
1130 Array<Face *> tris(sphere_tris_num + grid_tris_num);
1131 arena.reserve(3 * (sphere_verts_num + grid_verts_num) / 2,
1132 4 * (sphere_tris_num + grid_tris_num));
1134 fill_sphere_data(nrings,
1139 MutableSpan<Face *>(tris.begin(), sphere_tris_num),
1143 fill_grid_data(subdivs,
1149 MutableSpan<Face *>(tris.begin() + sphere_tris_num, grid_tris_num),
1158 out = trimesh_self_intersect(
mesh, &arena);
1161 int nf = sphere_tris_num;
1162 out = trimesh_nary_intersect(
1163 mesh, 2, [nf](
int t) {
return t < nf ? 0 : 1; },
false, &arena);
1166 std::cout <<
"Create time: " << time_create - time_start <<
"\n";
1167 std::cout <<
"Intersect time: " << time_intersect - time_create <<
"\n";
1168 std::cout <<
"Total time: " << time_intersect - time_start <<
"\n";
1170 write_obj_mesh(
out,
"spheregrid");
1175 static void gridgrid_test(
int x_level_1,
1189 int x_subdivs_1 = 1 << x_level_1;
1190 int y_subdivs_1 = 1 << y_level_1;
1191 int x_subdivs_2 = 1 << x_level_2;
1192 int y_subdivs_2 = 1 << y_level_2;
1193 int grid_verts_1_num;
1194 int grid_verts_2_num;
1195 int grid_tris_1_num;
1196 int grid_tris_2_num;
1197 get_grid_params(x_subdivs_1, y_subdivs_1,
true, &grid_verts_1_num, &grid_tris_1_num);
1198 get_grid_params(x_subdivs_2, y_subdivs_2,
true, &grid_verts_2_num, &grid_tris_2_num);
1199 Array<Face *> tris(grid_tris_1_num + grid_tris_2_num);
1200 arena.reserve(3 * (grid_verts_1_num + grid_verts_2_num) / 2,
1201 4 * (grid_tris_1_num + grid_tris_2_num));
1202 fill_grid_data(x_subdivs_1,
1208 MutableSpan<Face *>(tris.begin(), grid_tris_1_num),
1212 fill_grid_data(x_subdivs_2,
1218 MutableSpan<Face *>(tris.begin() + grid_tris_1_num, grid_tris_2_num),
1227 out = trimesh_self_intersect(
mesh, &arena);
1230 int nf = grid_tris_1_num;
1231 out = trimesh_nary_intersect(
1232 mesh, 2, [nf](
int t) {
return t < nf ? 0 : 1; },
false, &arena);
1235 std::cout <<
"Create time: " << time_create - time_start <<
"\n";
1236 std::cout <<
"Intersect time: " << time_intersect - time_create <<
"\n";
1237 std::cout <<
"Total time: " << time_intersect - time_start <<
"\n";
1239 write_obj_mesh(
out,
"gridgrid");
1244 TEST(mesh_intersect_perf, SphereSphere)
1246 spheresphere_test(512, 0.5,
false);
1249 TEST(mesh_intersect_perf, SphereSphereSelf)
1251 spheresphere_test(64, 0.5,
true);
1254 TEST(mesh_intersect_perf, SphereGrid)
1256 spheregrid_test(512, 4, 0.1,
false);
1259 TEST(mesh_intersect_perf, SphereGridSelf)
1261 spheregrid_test(64, 4, 0.1,
true);
1264 TEST(mesh_intersect_perf, GridGrid)
1266 gridgrid_test(8, 2, 4, 2, 0.1, 0.1, 0.0,
false);
1269 TEST(mesh_intersect_perf, GridGridTilt)
1271 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 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 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 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)
vec_base< double, 3 > double3
std::string to_string(const T &n)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
double PIL_check_seconds_timer(void)