567 const bool do_aspect_correct,
568 const bool do_mask_aa,
569 const bool do_feather)
571 const rctf default_bounds = {0.0f, 1.0f, 0.0f, 1.0f};
572 const float pixel_size = 1.0f /
float(
min_ii(width, height));
573 const float asp_xy[2] = {
574 (do_aspect_correct && width > height) ?
float(height) /
float(width) : 1.0f,
575 (do_aspect_correct && width < height) ?
float(width) /
float(height) : 1.0f};
577 const float zvec[3] = {0.0f, 0.0f, -1.0f};
588 for (masklay =
static_cast<MaskLayer *
>(
mask->masklayers.first), masklay_index = 0; masklay;
589 masklay = masklay->
next, masklay_index++)
594 uint open_spline_index = 0;
602 uint sf_vert_tot = 0;
603 uint tot_feather_quads = 0;
605#ifdef USE_SCANFILL_EDGE_WORKAROUND
606 uint tot_boundary_used = 0;
607 uint tot_boundary_found = 0;
626 float (*diff_points)[2];
629 float (*diff_feather_points)[2];
630 float (*diff_feather_points_flip)[2];
631 uint tot_diff_feather_points;
635 const uint resol = std::clamp(std::max(resol_a, resol_b), 4u, 512u);
641 spline, resol,
false, &tot_diff_feather_points);
645 tot_diff_feather_points = 0;
646 diff_feather_points =
nullptr;
649 if (tot_diff_point > 3) {
655 if (do_aspect_correct) {
656 if (width != height) {
661 if (width < height) {
662 fp = &diff_points[0][0];
663 ffp = tot_diff_feather_points ? &diff_feather_points[0][0] :
nullptr;
667 fp = &diff_points[0][1];
668 ffp = tot_diff_feather_points ? &diff_feather_points[0][1] :
nullptr;
672 for (
uint i = 0;
i < tot_diff_point;
i++, fp += 2) {
673 (*fp) = (((*fp) - 0.5f) / asp) + 0.5f;
676 if (tot_diff_feather_points) {
677 for (
uint i = 0;
i < tot_diff_feather_points;
i++, ffp += 2) {
678 (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f;
685 if (do_mask_aa ==
true) {
686 if (do_feather ==
false) {
687 tot_diff_feather_points = tot_diff_point;
691 diff_feather_points, diff_points, tot_diff_point, pixel_size,
false);
696 diff_feather_points, diff_points, tot_diff_point, pixel_size,
true);
704 spline, diff_feather_points, tot_diff_feather_points);
708 sf_vert_prev->
tmp.
u = sf_vert_tot;
711 sf_vert_prev->
keyindex = sf_vert_tot + tot_diff_point;
715 for (j = 1; j < tot_diff_point; j++) {
717 sf_vert->
tmp.
u = sf_vert_tot;
718 sf_vert->
keyindex = sf_vert_tot + tot_diff_point;
722 sf_vert = sf_vert_prev;
725 for (j = 0; j < tot_diff_point; j++) {
728#ifdef USE_SCANFILL_EDGE_WORKAROUND
729 if (diff_feather_points) {
736 sf_vert_prev = sf_vert;
737 sf_vert = sf_vert->
next;
740 if (diff_feather_points) {
741 BLI_assert(tot_diff_feather_points == tot_diff_point);
745 for (j = 0; j < tot_diff_feather_points; j++) {
751 tot_feather_quads += tot_diff_point;
756 if (diff_feather_points) {
760 "diff_feather_points_flip");
763 for (j = 0; j < tot_diff_point; j++) {
764 sub_v2_v2v2(co_diff, diff_points[j], diff_feather_points[j]);
765 add_v2_v2v2(diff_feather_points_flip[j], diff_points[j], co_diff);
769 spline, diff_feather_points, tot_diff_feather_points);
771 spline, diff_feather_points_flip, tot_diff_feather_points);
774 diff_feather_points_flip =
nullptr;
777 open_spline_ranges[open_spline_index].
vertex_offset = sf_vert_tot;
778 open_spline_ranges[open_spline_index].
vertex_total = tot_diff_point;
781 for (j = 0; j < tot_diff_point; j++) {
785 sf_vert->
tmp.
u = sf_vert_tot;
791 sf_vert->
tmp.
u = sf_vert_tot;
796 if (diff_feather_points_flip) {
798 &sf_ctx, diff_feather_points_flip[j], 1.0f);
802 sub_v2_v2v2(co_diff, diff_points[j], diff_feather_points[j]);
807 sf_vert->
tmp.
u = sf_vert_tot;
811 tot_feather_quads += 2;
815 tot_feather_quads -= 2;
818 if (diff_feather_points_flip) {
820 diff_feather_points_flip =
nullptr;
830 const float *fp_cent;
831 const float *fp_turn;
835 fp_cent = diff_points[0];
836 fp_turn = diff_feather_points[0];
838#define CALC_CAP_RESOL \
839 clampis_uint(uint(len_v2v2(fp_cent, fp_turn) / (pixel_size * SPLINE_RESOL_CAP_PER_PIXEL)), \
840 SPLINE_RESOL_CAP_MIN, \
841 SPLINE_RESOL_CAP_MAX)
846 for (k = 1; k < vertex_total_cap; k++) {
852 sf_vert->
tmp.
u = sf_vert_tot;
856 tot_feather_quads += vertex_total_cap;
861 fp_cent = diff_points[tot_diff_point - 1];
862 fp_turn = diff_feather_points[tot_diff_point - 1];
867 for (k = 1; k < vertex_total_cap; k++) {
873 sf_vert->
tmp.
u = sf_vert_tot;
877 tot_feather_quads += vertex_total_cap;
896 if (diff_feather_points) {
902 uint(*face_array)[4], *face;
907 int scanfill_flag = 0;
909 bool is_isect =
false;
910 ListBase isect_remvertbase = {
nullptr,
nullptr};
911 ListBase isect_remedgebase = {
nullptr,
nullptr};
920 cos = (
float *)face_coords;
922 sf_vert = sf_vert_next)
924 sf_vert_next = sf_vert->
next;
944 &sf_ctx, &isect_remvertbase, &isect_remedgebase)))
947 uint i = sf_vert_tot;
949 face_coords =
static_cast<float (*)[3]
>(
950 MEM_reallocN(face_coords,
sizeof(
float[3]) * (sf_vert_tot + sf_vert_tot_isect)));
952 cos = (&face_coords[sf_vert_tot][0]);
955 sf_vert = sf_vert->
next)
957 copy_v3_v3(cos, sf_vert->co);
958 sf_vert->tmp.u = i++;
962 sf_vert_tot += sf_vert_tot_isect;
977 uint sf_edge_array_num = 0;
978 if (tot_feather_quads) {
980 for (
int pass = 0; pass < 2; pass++) {
983 sf_edge_array_num += 1;
988 if (sf_edge_array_num > 0) {
991 for (
int pass = 0; pass < 2; pass++) {
994 sf_edge_array[edge_index++] = sf_edge;
1012 "maskrast_face_index");
1016 face = (
uint *)face_array;
1018 sf_tri = sf_tri->
next)
1020 *(face++) = sf_tri->
v3->
tmp.
u;
1021 *(face++) = sf_tri->
v2->
tmp.
u;
1022 *(face++) = sf_tri->
v1->
tmp.
u;
1034 if (sf_edge_array) {
1036 for (
uint i = 0;
i < sf_edge_array_num;
i++) {
1039 *(face++) = sf_edge->
v1->
tmp.
u;
1040 *(face++) = sf_edge->
v2->
tmp.
u;
1046#ifdef USE_SCANFILL_EDGE_WORKAROUND
1047 tot_boundary_found++;
1053#ifdef USE_SCANFILL_EDGE_WORKAROUND
1054 if (tot_boundary_found != tot_boundary_used) {
1055 BLI_assert(tot_boundary_found < tot_boundary_used);
1060 while (open_spline_index > 0) {
1061 const uint vertex_offset = open_spline_ranges[--open_spline_index].
vertex_offset;
1070 for (k = 0; k < vertex_total - 1; k++, j += 3) {
1089 if (open_spline_ranges[open_spline_index].
is_cyclic) {
1090 *(face++) = vertex_offset + 0;
1093 *(face++) = vertex_offset + 1;
1098 *(face++) = vertex_offset + 0;
1099 *(face++) = vertex_offset + 2;
1105 uint midvidx = vertex_offset;
1109 j = midvidx + (vertex_total * 3);
1111 for (k = 0; k < vertex_total_cap_head - 2; k++, j++) {
1112 *(face++) = midvidx + 0;
1113 *(face++) = midvidx + 0;
1120 j = vertex_offset + (vertex_total * 3);
1123 *(face++) = midvidx + 0;
1124 *(face++) = midvidx + 0;
1125 *(face++) = midvidx + 1;
1130 *(face++) = midvidx + 0;
1131 *(face++) = midvidx + 0;
1132 *(face++) = j + vertex_total_cap_head - 2;
1133 *(face++) = midvidx + 2;
1141 j = vertex_offset + (vertex_total * 3) + (vertex_total_cap_head - 1);
1143 midvidx = vertex_offset + (vertex_total * 3) - 3;
1145 for (k = 0; k < vertex_total_cap_tail - 2; k++, j++) {
1146 *(face++) = midvidx;
1147 *(face++) = midvidx;
1154 j = vertex_offset + (vertex_total * 3) + (vertex_total_cap_head - 1);
1157 *(face++) = midvidx + 0;
1158 *(face++) = midvidx + 0;
1160 *(face++) = midvidx + 1;
1164 *(face++) = midvidx + 0;
1165 *(face++) = midvidx + 0;
1166 *(face++) = midvidx + 2;
1167 *(face++) = j + vertex_total_cap_tail - 2;
1177 "%u %u (%u %u), %u\n",
1179 sf_tri_tot + tot_feather_quads,
1182 tot_boundary_used - tot_boundary_found);
1185#ifdef USE_SCANFILL_EDGE_WORKAROUND
1186 BLI_assert(face_index + (tot_boundary_used - tot_boundary_found) ==
1187 sf_tri_tot + tot_feather_quads);
1189 BLI_assert(face_index == sf_tri_tot + tot_feather_quads);
1195#ifdef USE_SCANFILL_EDGE_WORKAROUND
1196 layer->
face_tot = (sf_tri_tot + tot_feather_quads) -
1197 (tot_boundary_used - tot_boundary_found);
1199 layer->
face_tot = (sf_tri_tot + tot_feather_quads);