24int DiagSplit::alloc_verts(
int num)
26 const int index = num_verts;
31SubEdge *DiagSplit::alloc_edge(
const int v0,
const int v1,
const int depth,
bool &was_missing)
33 const SubEdge edge(v0, v1, depth);
34 const auto it = edges.find(edge);
35 was_missing = (it == edges.end());
36 return const_cast<SubEdge *
>(was_missing ? &*(edges.emplace(edge).first) : &*it);
43 const bool want_to_own_edge,
44 const bool want_to_own_vertex)
47 sub_edge->
edge = (v0 < v1) ? alloc_edge(v0, v1, depth, was_missing) :
48 alloc_edge(v1, v0, depth, was_missing);
50 sub_edge->
own_edge = was_missing && want_to_own_edge;
53 if (want_to_own_vertex) {
54 if (v0 < owned_verts.size()) {
56 if (!owned_verts[v0]) {
57 owned_verts[v0] =
true;
68void DiagSplit::alloc_subpatch(
SubPatch &&sub)
70 assert(sub.edges[0].edge->T >= 1);
71 assert(sub.edges[1].edge->T >= 1);
72 assert(sub.edges[2].edge->T >= 1);
74 assert(sub.edges[3].edge->T >= 1);
77 sub.inner_grid_vert_offset = alloc_verts(sub.calc_num_inner_verts());
78 sub.triangles_offset = num_triangles;
79 num_triangles += sub.calc_num_triangles();
81 subpatches.push_back(std::move(sub));
88 patch->
eval(&
P,
nullptr,
nullptr,
nullptr, uv.
x, uv.
y);
96std::pair<int, float> DiagSplit::T(
const Patch *patch,
100 const bool recursive_resolve)
103 if (uv_end.
x < uv_start.
x || uv_end.
y < uv_start.
y) {
104 swap(uv_start, uv_end);
109 float Lsum_world = 0.0f;
111 float3 Plast = to_world(patch, uv_start);
113 for (
int i = 1;
i < params.test_steps;
i++) {
114 const float t =
i / (
float)(params.test_steps - 1);
116 const float3 P = to_world(patch, uv_start + t * (uv_end - uv_start));
118 float L =
len(
P - Plast);
122 Camera *cam = params.camera;
134 const int tmin = (int)
ceilf(Lsum / params.dicing_rate);
135 const int tmax = (int)
ceilf(
136 (params.test_steps - 1) * Lmax /
138 int res =
max(tmax, 1);
140 if (tmax - tmin > params.split_threshold) {
141 if (!recursive_resolve) {
145 const float2 uv_mid = (uv_start + uv_end) * 0.5f;
146 const auto result_a =
T(patch, uv_start, uv_mid, depth,
true);
147 const auto result_b =
T(patch, uv_mid, uv_end, depth,
true);
148 res = result_a.first + result_b.first;
149 Lsum_world = result_a.second + result_b.second;
157 res = limit_edge_factor(patch, uv_start, uv_end, res);
165 return std::make_pair(res, Lsum_world);
168int DiagSplit::limit_edge_factor(
const Patch *patch,
173 const int max_t = 1 << params.max_level;
174 int max_t_for_edge = int(max_t *
len(uv_start - uv_end));
177 max_t_for_edge >>= 1;
180 const int limit_T = (max_t_for_edge <= 1) ? 1 :
min(T, max_t_for_edge);
186void DiagSplit::assign_edge_factor(
SubEdge *edge,
190 const bool recursive_resolve)
194 const auto result =
T(patch, uv_start, uv_end, edge->
depth, recursive_resolve);
199 if (edge->
depth == -1 && edge->
T == 1) {
208void DiagSplit::resolve_edge_factors(
const SubPatch &sub)
216 assign_edge_factor(edge0, sub.
patch, sub.
uvs[0], sub.
uvs[1],
true);
219 assign_edge_factor(edge1, sub.
patch, sub.
uvs[1], sub.
uvs[2],
true);
224 assign_edge_factor(edge2, sub.
patch, sub.
uvs[2], sub.
uvs[0],
true);
231 assign_edge_factor(edge2, sub.
patch, sub.
uvs[2], sub.
uvs[3],
true);
234 assign_edge_factor(edge3, sub.
patch, sub.
uvs[3], sub.
uvs[0],
true);
248 swap(uv_start, uv_end);
251 SubEdge *edge = subedge->
edge;
255 const float2 P = 0.5f * (uv_start + uv_end);
261 SubEdge *edge_a = alloc_edge(
263 SubEdge *edge_b = alloc_edge(
265 assign_edge_factor(edge_a, patch, uv_start,
P);
266 assign_edge_factor(edge_b, patch,
P, uv_end);
270 alloc_edge(subedge_a,
276 alloc_edge(subedge_b,
288 assert(
P.x >= 0 &&
P.x <= 1.0f &&
P.y >= 0.0f &&
P.y <= 1.0f);
293 const int mid = edge->
T / 2;
302 SubEdge *edge_a = alloc_edge(
304 SubEdge *edge_b = alloc_edge(
307 edge_b->
T = edge->
T - mid;
313 alloc_edge(subedge_a,
319 alloc_edge(subedge_b,
332 assert(
P.x >= 0 &&
P.x <= 1.0f &&
P.y >= 0.0f &&
P.y <= 1.0f);
337void DiagSplit::split_quad(
SubPatch &&sub)
340 resolve_edge_factors(sub);
359 if (split_u && split_v) {
362 const float bias = 1.00012345f;
375 if (!split_u && !split_v) {
377 alloc_subpatch(std::move(sub));
386 split_quad_into_triangles(std::move(sub));
394 for (
int i = 0;
i < 4;
i++) {
395 sub_a.edges[
i].own_edge =
false;
396 sub_a.edges[
i].own_vertex =
false;
397 sub_b.edges[
i].own_edge =
false;
398 sub_b.edges[
i].own_vertex =
false;
402 SubPatch::Edge *sub_across_0;
403 SubPatch::Edge *sub_across_1;
404 SubPatch::Edge *sub_a_across_0;
405 SubPatch::Edge *sub_a_across_1;
406 SubPatch::Edge *sub_b_across_0;
407 SubPatch::Edge *sub_b_across_1;
409 SubPatch::Edge *sub_a_split;
410 SubPatch::Edge *sub_b_split;
428 sub_across_0 = &sub.
edges[0];
429 sub_across_1 = &sub.
edges[2];
430 sub_a_across_0 = &sub_a.edges[0];
431 sub_a_across_1 = &sub_a.edges[2];
432 sub_b_across_0 = &sub_b.edges[0];
433 sub_b_across_1 = &sub_b.edges[2];
440 sub_a_split = &sub_a.edges[1];
441 sub_b_split = &sub_b.edges[3];
443 uv_a = &sub_a.uvs[2];
444 uv_b = &sub_a.uvs[1];
445 uv_c = &sub_b.uvs[3];
446 uv_d = &sub_b.uvs[0];
458 sub_across_0 = &sub.
edges[3];
459 sub_across_1 = &sub.
edges[1];
460 sub_a_across_0 = &sub_a.edges[3];
461 sub_a_across_1 = &sub_a.edges[1];
462 sub_b_across_0 = &sub_b.edges[3];
463 sub_b_across_1 = &sub_b.edges[1];
470 sub_a_split = &sub_a.edges[0];
471 sub_b_split = &sub_b.edges[2];
473 uv_a = &sub_a.uvs[1];
474 uv_b = &sub_a.uvs[0];
475 uv_c = &sub_b.uvs[2];
476 uv_d = &sub_b.uvs[3];
480 const float2 uv0 = split_edge(
481 sub.
patch, sub_across_0, sub_a_across_0, sub_b_across_0, *uv_d, *uv_b);
482 const float2 uv1 = split_edge(
483 sub.
patch, sub_across_1, sub_b_across_1, sub_a_across_1, *uv_a, *uv_c);
498 const int split_edge_depth = (split_u) ?
501 alloc_edge(sub_a_split,
507 alloc_edge(sub_b_split,
515 assign_edge_factor(sub_a_split->
edge, sub.
patch, uv0, uv1);
518 split_quad(std::move(sub_a));
519 split_quad(std::move(sub_b));
522void DiagSplit::split_quad_into_triangles(
SubPatch &&sub)
533 for (
int i = 0;
i < 4;
i++) {
534 sub_a.edges[
i].own_edge =
false;
535 sub_a.edges[
i].own_vertex =
false;
536 sub_b.edges[
i].own_edge =
false;
537 sub_b.edges[
i].own_vertex =
false;
545 sub_a.edges[0] = sub.
edges[0];
546 sub_a.edges[1] = sub.
edges[1];
547 sub_a.uvs[0] = sub.
uvs[0];
548 sub_a.uvs[1] = sub.
uvs[1];
549 sub_a.uvs[2] = sub.
uvs[2];
550 alloc_edge(&sub_a.edges[2],
557 sub_b.edges[1] = sub.
edges[2];
558 sub_b.edges[2] = sub.
edges[3];
559 sub_b.uvs[0] = sub.
uvs[0];
560 sub_b.uvs[1] = sub.
uvs[2];
561 sub_b.uvs[2] = sub.
uvs[3];
562 alloc_edge(&sub_b.edges[0],
570 assign_edge_factor(sub_b.edges[0].edge, sub.
patch, sub.
uvs[0], sub.
uvs[2]);
573 split_triangle(std::move(sub_a));
574 split_triangle(std::move(sub_b));
577void DiagSplit::split_triangle(
SubPatch &&sub)
582 resolve_edge_factors(sub);
588 alloc_subpatch(std::move(sub));
594 const float bias = 1.00012345f;
598 float max_length = 0.0f;
599 int split_index_0 = -1;
600 for (
int i = 0;
i < 3;
i++) {
613 for (
int i = 0;
i < 4;
i++) {
614 sub_a.edges[
i].own_edge =
false;
615 sub_a.edges[
i].own_vertex =
false;
616 sub_b.edges[
i].own_edge =
false;
617 sub_b.edges[
i].own_vertex =
false;
620 const int split_index_1 = (split_index_0 + 1) % 3;
621 const int split_index_2 = (split_index_0 + 2) % 3;
623 sub_a.edges[2] = sub.
edges[split_index_2];
624 sub_b.edges[1] = sub.
edges[split_index_1];
639 &sub.
edges[split_index_0],
642 sub.
uvs[split_index_0],
643 sub.
uvs[split_index_1]);
646 sub_a.uvs[0] = sub.
uvs[split_index_0];
647 sub_a.uvs[1] = uv_split;
648 sub_a.uvs[2] = sub.
uvs[split_index_2];
649 sub_b.uvs[0] = uv_split;
650 sub_b.uvs[1] = sub.
uvs[split_index_1];
651 sub_b.uvs[2] = sub.
uvs[split_index_2];
657 const int split_edge_depth = sub.
edges[split_index_0].
edge->
depth + 1;
659 alloc_edge(&sub_a.edges[1], vsplit, vopposite, split_edge_depth,
true,
false);
660 alloc_edge(&sub_b.edges[2], vopposite, vsplit, split_edge_depth,
true,
false);
663 const float2 uv_opposite = sub.
uvs[split_index_2];
664 assign_edge_factor(sub_a.edges[1].edge, sub.
patch, uv_split, uv_opposite);
667 split_triangle(std::move(sub_a));
668 split_triangle(std::move(sub_b));
671void DiagSplit::split_quad(
const Mesh::SubdFace &face,
const int face_index,
const Patch *patch)
673 const int *subd_face_corners = params.mesh->get_subd_face_corners().data();
674 const int v0 = subd_face_corners[face.
start_corner + 0];
675 const int v1 = subd_face_corners[face.
start_corner + 1];
677 const int v3 = subd_face_corners[face.
start_corner + 3];
679 const int depth = -1;
681 SubPatch subpatch(patch, face_index);
682 alloc_edge(&subpatch.edges[0], v0, v1, depth,
true,
true);
683 alloc_edge(&subpatch.edges[1], v1,
v2, depth,
true,
true);
684 alloc_edge(&subpatch.edges[2],
v2, v3, depth,
true,
true);
685 alloc_edge(&subpatch.edges[3], v3, v0, depth,
true,
true);
693 split_quad(std::move(subpatch));
697 const int face_index,
698 const Patch *patches,
699 const size_t patches_byte_stride)
701 const int *subd_face_corners = params.mesh->get_subd_face_corners().data();
702 const int v2 = alloc_verts(1);
708 for (
int corner = 0; corner < face.
num_corners; corner++) {
712 alloc_edge(&edges[corner],
v, vnext, depth,
true,
true);
714 edges[corner].edge->mid_vert_index = alloc_verts(1);
719 for (
int corner = 0; corner < face.
num_corners; corner++) {
720 const Patch *patch = (
const Patch *)(((
char *)patches) + (corner * patches_byte_stride));
733 SubPatch::Edge &edge0 = edges[corner];
740 SubPatch subpatch(patch, face_index, corner);
741 alloc_edge(&subpatch.edges[0], v0, v1, depth,
false,
false);
742 alloc_edge(&subpatch.edges[1], v1,
v2, depth,
true,
false);
743 alloc_edge(&subpatch.edges[2],
v2, v3, depth,
true, corner == 0);
744 alloc_edge(&subpatch.edges[3], v3, v0, depth,
false,
false);
746 subpatch.edges[0].own_edge = edge0.
own_edge;
747 subpatch.edges[0].own_vertex = edge0.
own_vertex;
748 subpatch.edges[3].own_edge = edge3.
own_edge;
749 subpatch.edges[3].own_vertex = edge3.
own_edge;
752 split_quad(std::move(subpatch));
763 num_verts = params.mesh->get_num_subd_base_verts();
766 owned_verts.resize(num_verts,
false);
769 for (
int f = 0; f < params.mesh->get_num_subd_faces(); f++) {
771 const Patch *patch = (
const Patch *)(((
char *)patches) +
774 split_quad(face, f, patch);
777 split_ngon(face, f, patch, patches_byte_stride);
ATTR_WARN_UNUSED_RESULT const size_t num
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
DiagSplit(const SubdParams ¶ms)
void split_patches(const Patch *patches, const size_t patches_byte_stride)
virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, const float u, float v) const =0
enum SubPatch::@271217051357320143155373165321151177022113114126 shape
#define CCL_NAMESPACE_END
#define assert(assertion)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
VecBase< float, 2 > float2
VecBase< float, 3 > float3
ccl_device_inline float interp(const float a, const float b, const float t)
float world_to_raster_size(const float3 P)
int start_vert_index() const
int mid_vert_index() const
int end_vert_index() const