114 const double *override_camera_loc,
115 const bool override_cam_is_persp,
116 const bool allow_overlapping_edges,
117 const double m_view_projection[4][4],
118 const double camera_dir[3],
119 const float cam_shift_x,
120 const float cam_shift_y,
130 bool do_intersection,
172 uchar material_mask_bits,
207 cut_start_before = seg;
208 new_seg1 = cut_start_before;
211 if (seg->next ==
nullptr) {
215 if (i_seg->
ratio > start + 1
e-09 && start > seg->ratio) {
216 cut_start_before = i_seg;
228 cut_end_before = seg;
229 new_seg2 = cut_end_before;
235 cut_end_before = seg;
236 new_seg2 = cut_end_before;
241 if (seg->ratio > end) {
242 cut_end_before = seg;
249 if (new_seg1 ==
nullptr) {
252 if (new_seg2 ==
nullptr) {
255 cut_end_before = new_seg2;
262 if (cut_start_before) {
263 if (cut_start_before != new_seg1) {
265 i_seg = cut_start_before->
prev ? cut_start_before->
prev :
nullptr;
284 if (cut_end_before) {
286 if (cut_end_before != new_seg2) {
287 i_seg = cut_end_before->
prev ? cut_end_before->
prev :
nullptr;
308 new_seg1->
ratio = start;
310 new_seg2->ratio = end;
314 new_seg2 = new_seg2->next;
319 seg->occlusion += mat_occlusion;
320 seg->material_mask_bits |= material_mask_bits;
335 seg->shadow_mask_bits |= shadow_bits;
344 if (prev_seg && prev_seg->
occlusion == seg->occlusion &&
355 min_occ = std::min<int8_t>(min_occ, seg->occlusion);
359 e->min_occ = min_occ;
404 for (
int i = 0; i < nba->triangle_count; i++) {
416 tri->testing_e[thread_id] =
e;
489 for (i = 0; i < thread_count; i++) {
514 cl = (v0[0] -
v[0]) * (v1[1] -
v[1]) - (v0[1] -
v[1]) * (v1[0] -
v[0]);
517 cl = (v1[0] -
v[0]) * (
v2[1] -
v[1]) - (v1[1] -
v[1]) * (
v2[0] -
v[0]);
524 cl = (
v2[0] -
v[0]) * (v0[1] -
v[1]) - (
v2[1] -
v[1]) * (v0[0] -
v[0]);
541 double c1 = 1, c2 = 0;
547 if (v1[0] == v0[0] && v1[1] == v0[1]) {
552 c1 =
ratiod(v0[0], v1[0],
v[0]);
556 c2 =
ratiod(v0[1], v1[1],
v[1]);
563 c2 =
ratiod(v0[1], v1[1],
v[1]);
567 c1 =
ratiod(v0[0], v1[0],
v[0]);
603 cl = (v0[0] -
v[0]) * (v1[1] -
v[1]) - (v0[1] -
v[1]) * (v1[0] -
v[0]);
606 cl = (v1[0] -
v[0]) * (
v2[1] -
v[1]) - (v1[1] -
v[1]) * (
v2[0] -
v[0]);
607 if ((r = c * cl) < 0) {
613 cl = (
v2[0] -
v[0]) * (v0[1] -
v[1]) - (
v2[1] -
v[1]) * (v0[0] -
v[0]);
614 if ((r = c * cl) < 0) {
620 cl = (v0[0] -
v[0]) * (v1[1] -
v[1]) - (v0[1] -
v[1]) * (v1[0] -
v[0]);
621 if ((r = c * cl) < 0) {
744 tri->
flags |= intersection_only;
749 return ((tri->
v[v1] ==
e->v1 && tri->
v[
v2] ==
e->v2) ||
750 (tri->
v[
v2] ==
e->v1 && tri->
v[v1] ==
e->v2));
773 bool allow_boundaries,
774 double m_view_projection[4][4],
783 double span_v1[3], span_v2[3], dot_v1, dot_v2;
785 int v_count = *r_v_count;
786 int e_count = *r_e_count;
787 int t_count = *r_t_count;
812#define INCREASE_EDGE \
813 new_e = &((LineartEdge *)e_eln->pointer)[e_count]; \
816 es = static_cast<LineartEdgeSegment *>( \
817 lineart_mem_acquire(&ld->render_data_pool, sizeof(LineartEdgeSegment))); \
818 BLI_addtail(&e->segments, es);
820#define SELECT_EDGE(e_num, v1_link, v2_link, new_tri) \
821 if (tri_adj->e[e_num]) { \
822 old_e = tri_adj->e[e_num]; \
823 new_flag = old_e->flags; \
824 old_e->flags = MOD_LINEART_EDGE_FLAG_CHAIN_PICKED; \
825 lineart_discard_duplicated_edges(old_e); \
829 e->v1->index = (v1_link)->index; \
830 e->v2->index = (v1_link)->index; \
831 e->flags = new_flag; \
832 e->object_ref = ob; \
833 e->t1 = ((old_e->t1 == tri) ? (new_tri) : (old_e->t1)); \
834 e->t2 = ((old_e->t2 == tri) ? (new_tri) : (old_e->t2)); \
835 lineart_add_edge_to_array(&ld->pending_edges, e); \
838#define RELINK_EDGE(e_num, new_tri) \
839 if (tri_adj->e[e_num]) { \
840 old_e = tri_adj->e[e_num]; \
841 old_e->t1 = ((old_e->t1 == tri) ? (new_tri) : (old_e->t1)); \
842 old_e->t2 = ((old_e->t2 == tri) ? (new_tri) : (old_e->t2)); \
845#define REMOVE_TRIANGLE_EDGE \
846 if (tri_adj->e[0]) { \
847 tri_adj->e[0]->flags = MOD_LINEART_EDGE_FLAG_CHAIN_PICKED; \
848 lineart_discard_duplicated_edges(tri_adj->e[0]); \
850 if (tri_adj->e[1]) { \
851 tri_adj->e[1]->flags = MOD_LINEART_EDGE_FLAG_CHAIN_PICKED; \
852 lineart_discard_duplicated_edges(tri_adj->e[1]); \
854 if (tri_adj->e[2]) { \
855 tri_adj->e[2]->flags = MOD_LINEART_EDGE_FLAG_CHAIN_PICKED; \
856 lineart_discard_duplicated_edges(tri_adj->e[2]); \
859 switch (in0 + in1 + in2) {
900 a = dot_v1 / (dot_v1 + dot_v2);
911 a = dot_v1 / (dot_v1 + dot_v2);
919 if (allow_boundaries) {
939 tri1->
v[0] = tri->
v[0];
953 a = dot_v1 / (dot_v1 + dot_v2);
962 a = dot_v1 / (dot_v1 + dot_v2);
968 if (allow_boundaries) {
982 tri1->
v[2] = tri->
v[2];
994 a = dot_v1 / (dot_v1 + dot_v2);
1003 a = dot_v1 / (dot_v1 + dot_v2);
1009 if (allow_boundaries) {
1021 tri1->
v[0] = &vt[0];
1022 tri1->
v[1] = tri->
v[1];
1023 tri1->
v[2] = &vt[1];
1065 a = dot_v2 / (dot_v1 + dot_v2);
1076 a = dot_v2 / (dot_v1 + dot_v2);
1084 if (allow_boundaries) {
1101 tri1->
v[0] = tri->
v[1];
1102 tri1->
v[1] = &vt[1];
1103 tri1->
v[2] = &vt[0];
1105 tri2->
v[0] = &vt[1];
1106 tri2->
v[1] = tri->
v[1];
1107 tri2->
v[2] = tri->
v[2];
1121 a = dot_v1 / (dot_v1 + dot_v2);
1130 a = dot_v1 / (dot_v1 + dot_v2);
1136 if (allow_boundaries) {
1150 tri1->
v[0] = tri->
v[2];
1151 tri1->
v[1] = &vt[1];
1152 tri1->
v[2] = &vt[0];
1154 tri2->
v[0] = &vt[1];
1155 tri2->
v[1] = tri->
v[2];
1156 tri2->
v[2] = tri->
v[0];
1170 a = dot_v1 / (dot_v1 + dot_v2);
1179 a = dot_v1 / (dot_v1 + dot_v2);
1185 if (allow_boundaries) {
1199 tri1->
v[0] = tri->
v[0];
1200 tri1->
v[1] = &vt[1];
1201 tri1->
v[2] = &vt[0];
1203 tri2->
v[0] = &vt[1];
1204 tri2->
v[1] = tri->
v[0];
1205 tri2->
v[2] = tri->
v[1];
1215 *r_v_count = v_count;
1216 *r_e_count = e_count;
1217 *r_t_count = t_count;
1222#undef REMOVE_TRIANGLE_EDGE
1231 int v_count = 0, t_count = 0, e_count = 0;
1236 double view_dir[3], clip_advance[3];
1261#define LRT_CULL_ENSURE_MEMORY \
1262 if (v_count > 60) { \
1263 v_eln->element_count = v_count; \
1264 v_eln = lineart_memory_get_vert_space(ld); \
1267 if (t_count > 60) { \
1268 t_eln->element_count = t_count; \
1269 t_eln = lineart_memory_get_triangle_space(ld); \
1272 if (e_count > 60) { \
1273 e_eln->element_count = e_count; \
1274 e_eln = lineart_memory_get_edge_space(ld); \
1278#define LRT_CULL_DECIDE_INSIDE \
1280 in0 = 0, in1 = 0, in2 = 0; \
1283 if (tri->v[0]->fbcoord[use_w] > clip_end) { \
1286 if (tri->v[1]->fbcoord[use_w] > clip_end) { \
1289 if (tri->v[2]->fbcoord[use_w] > clip_end) { \
1295 if (tri->v[0]->fbcoord[use_w] < clip_start) { \
1298 if (tri->v[1]->fbcoord[use_w] < clip_start) { \
1301 if (tri->v[2]->fbcoord[use_w] < clip_start) { \
1307 int in0 = 0, in1 = 0, in2 = 0;
1320 ob =
static_cast<Object *
>(eln->object_ref);
1321 for (i = 0; i < eln->element_count; i++) {
1353#undef LRT_CULL_ENSURE_MEMORY
1354#undef LRT_CULL_DECIDE_INSIDE
1367 for (i = 0; i < eln->element_count; i++) {
1380 for (
int i = 0; i < eln->element_count; i++) {
1401 const float bounds[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, -1.0f}, {1.0f, 1.0f}};
1403#define LRT_VERT_OUT_OF_BOUND(v) \
1404 (v->fbcoord[0] < -1 || v->fbcoord[0] > 1 || v->fbcoord[1] < -1 || v->fbcoord[1] > 1)
1408 for (
int i = 0; i < eln->element_count; i++) {
1409 if (!
e[i].v1 || !
e[i].
v2) {
1464#define LRT_MESH_EDGE_TYPES_COUNT 6
1519 void *__restrict chunk_join,
1520 void *__restrict chunk)
1544 if (i < edge_nabr[i].
e) {
1548 bool face_mark_filtered =
false;
1551 bool only_contour =
false;
1552 if (enable_face_mark) {
1556 ff1 = &((
FreestyleFace *)mesh->face_data.layers[index].data)[tri_faces[i / 3]];
1558 if (edge_nabr[i].
e > -1) {
1559 ff2 = &((
FreestyleFace *)mesh->face_data.layers[index].data)[tri_faces[edge_nabr[i].
e / 3]];
1571 face_mark_filtered =
true;
1576 face_mark_filtered =
true;
1580 face_mark_filtered = !face_mark_filtered;
1582 if (!face_mark_filtered) {
1585 only_contour =
true;
1590 if (enable_face_mark && !face_mark_filtered && !only_contour) {
1595 if (edge_nabr[i].
e == -1) {
1605 int f1 = i / 3, f2 = edge_nabr[i].
e / 3;
1611 vert = &e_feat_data->
v_array[edge_nabr[i].
v1];
1613 double view_vector_persp[3];
1614 double *view_vector = view_vector_persp;
1615 double dot_v1 = 0, dot_v2 = 0;
1630 if ((result = dot_v1 * dot_v2) <= 0 && (dot_v1 + dot_v2)) {
1642 if (material_back_face) {
1653 view_vector = view_vector_persp;
1664 if ((result = dot_v1 * dot_v2) <= 0 && (dot_v1 + dot_v2)) {
1669 if (!only_contour) {
1671 bool do_crease =
true;
1682 int mat1 = material_indices.
is_empty() ? 0 : material_indices[tri_faces[f1]];
1683 int mat2 = material_indices.
is_empty() ? 0 : material_indices[tri_faces[f2]];
1702 if (!edge_flag_result) {
1707 const int3 real_edges = corner_tri_get_real_edges(e_feat_data->
edges,
1710 corner_tris[i / 3]);
1712 if (real_edges[i % 3] >= 0) {
1722 fe = &((
FreestyleEdge *)mesh->edge_data.layers[index].data)[real_edges[i % 3]];
1729 edge_nabr[i].
flags = edge_flag_result;
1731 if (edge_flag_result) {
1760 pe->
array = new_array;
1782 pe->
array = new_array;
1836 const int face_i = tri_task_data->
tri_faces[i];
1844 int v1 = corner_verts[corner_tri[0]];
1845 int v2 = corner_verts[corner_tri[1]];
1846 int v3 = corner_verts[corner_tri[2]];
1848 tri->
v[0] = &vert_arr[v1];
1849 tri->
v[1] = &vert_arr[
v2];
1850 tri->
v[2] = &vert_arr[v3];
1910 adj_e->
v1 = corner_verts[tri[i % 3]];
1911 adj_e->
v2 = corner_verts[tri[(i + 1) % 3]];
1912 if (adj_e->
v1 > adj_e->
v2) {
1913 std::swap(adj_e->
v1, adj_e->
v2);
1917 edge_nabr->
v1 = adj_e->
v1;
1918 edge_nabr->
v2 = adj_e->
v2;
1919 edge_nabr->
flags = 0;
1926 int a = p1.
v1 - p2.
v1;
1927 int b = p1.
v2 - p2.
v2;
1955 en_data.
adj_e = adj_e;
1959 en_data.
tri_faces = mesh->corner_tri_faces();
1965 for (
int i = 0; i < total_edges - 1; i++) {
1966 if (adj_e[i].v1 == adj_e[i + 1].v1 && adj_e[i].
v2 == adj_e[i + 1].
v2) {
1967 edge_nabr[adj_e[i].
e].
e = adj_e[i + 1].
e;
1968 edge_nabr[adj_e[i + 1].
e].
e = adj_e[i].
e;
1983 if (!mesh->edges_num) {
1988 const Span<int3> corner_tris = mesh->corner_tris();
1990 const VArraySpan material_indices = *attributes.lookup<
int>(
"material_index", AttrDomain::Face);
1993 bool can_find_freestyle_edge =
false;
1995 if (layer_index != -1) {
1996 can_find_freestyle_edge =
true;
1999 bool can_find_freestyle_face =
false;
2001 if (layer_index != -1) {
2002 can_find_freestyle_face =
true;
2026 ob_info->
v_eln = elem_link_node;
2028 bool use_auto_smooth =
false;
2029 float crease_angle = 0;
2051 int usage = ob_info->
usage;
2056 elem_link_node->
flags |
2075 vert_data.
positions = mesh->vert_positions();
2076 vert_data.
v_arr = la_v_arr;
2092 tri_data.
positions = mesh->vert_positions();
2094 tri_data.
tri_faces = mesh->corner_tri_faces();
2098 tri_data.
tri_arr = la_tri_arr;
2119 const VArray<bool> sharp_edges = *attributes.lookup_or_default<
bool>(
2120 "sharp_edge", AttrDomain::Edge,
false);
2121 const VArray<bool> sharp_faces = *attributes.lookup_or_default<
bool>(
2122 "sharp_face", AttrDomain::Face,
false);
2125 edge_feat_data.
ld = la_data;
2126 edge_feat_data.mesh = mesh;
2128 edge_feat_data.material_indices = material_indices;
2129 edge_feat_data.edges = mesh->edges();
2130 edge_feat_data.corner_verts = mesh->corner_verts();
2131 edge_feat_data.corner_edges = mesh->corner_edges();
2132 edge_feat_data.corner_tris = corner_tris;
2133 edge_feat_data.tri_faces = mesh->corner_tri_faces();
2134 edge_feat_data.sharp_edges = sharp_edges;
2135 edge_feat_data.sharp_faces = sharp_faces;
2137 edge_feat_data.tri_array = la_tri_arr;
2138 edge_feat_data.v_array = la_v_arr;
2139 edge_feat_data.crease_threshold = crease_angle;
2140 edge_feat_data.use_auto_smooth = use_auto_smooth;
2141 edge_feat_data.use_freestyle_face = can_find_freestyle_face;
2142 edge_feat_data.use_freestyle_edge = can_find_freestyle_edge;
2143 if (edge_feat_data.use_freestyle_face) {
2147 if (edge_feat_data.use_freestyle_edge) {
2156 &edge_feat_settings);
2166 if (loose_edges.
count > 0) {
2202 la_edge = la_edge_arr;
2203 la_seg = la_seg_arr;
2205 for (
int i = 0; i < total_edges; i++) {
2208 if (i < edge_nabr->
e) {
2213 if (edge_nabr->
flags == 0) {
2222 if (!(use_type & edge_nabr->
flags)) {
2226 la_edge->
v1 = &la_v_arr[edge_nabr->
v1];
2227 la_edge->
v2 = &la_v_arr[edge_nabr->
v2];
2233 if (edge_nabr->
e != -1) {
2234 findex = edge_nabr->
e / 3;
2240 la_edge->
flags = use_type;
2268 edge_added = la_edge;
2281 for (
int i = 0; i < loose_data.
loose_count; i++) {
2283 la_edge->
v1 = &la_v_arr[edge[0]];
2284 la_edge->
v2 = &la_v_arr[edge[1]];
2375 if (object_has_special_usage) {
2418 int this_face_count)
2422 for (
int i = 0; i < thread_count; i++) {
2423 if (olti_list[i].total_faces < min_face) {
2425 use_olti = &olti_list[i];
2449 for (
int i = 0; i < 8; i++) {
2453 co[i][0] -= shift_x * 2 * co[i][3];
2454 co[i][1] -= shift_y * 2 * co[i][3];
2457 bool cond[6] = {
true,
true,
true,
true,
true,
true};
2460 for (
int i = 0; i < 8; i++) {
2461 cond[0] &= (co[i][0] < -co[i][3]);
2462 cond[1] &= (co[i][0] > co[i][3]);
2463 cond[2] &= (co[i][1] < -co[i][3]);
2464 cond[3] &= (co[i][1] > co[i][3]);
2465 cond[4] &= (co[i][2] < -co[i][3]);
2466 cond[5] &= (co[i][2] > co[i][3]);
2468 for (
int i = 0; i < 6; i++) {
2481 const float use_mat[4][4],
2510 if ((!use_mesh) || use_mesh->
runtime->edit_mesh) {
2552 bool allow_duplicates,
2553 bool do_shadow_casting,
2557 double proj[4][4], view[4][4], result[4][4];
2560 if (!do_shadow_casting) {
2593 if (
G.debug_value == 4000) {
2598 int bound_box_discard_count = 0;
2612 if (allow_duplicates) {
2618 deg_iter_settings.
flags = flags;
2643 eval_ob->object_to_world().ptr(),
2654 if (
G.debug_value == 4000) {
2655 printf(
"thread count: %d\n", thread_count);
2657 for (
int i = 0; i < thread_count; i++) {
2671 for (
int i = 0; i < thread_count; i++) {
2676 edge_count += obi->pending_edges.next;
2681 for (
int i = 0; i < thread_count; i++) {
2687 int v_count = obi->v_eln->element_count;
2688 obi->v_eln->global_index_offset = global_i;
2689 for (
int vi = 0; vi < v_count; vi++) {
2690 v[vi].index += global_i;
2696 obi->global_i_offset = global_i;
2697 global_i += v_count;
2702 if (
G.debug_value == 4000) {
2704 printf(
"Line art loading time: %lf\n", t_elapsed);
2705 printf(
"Discarded %d object from bound box check\n", bound_box_discard_count);
2718 if (tri->
v[0] == vt) {
2723 if (tri->
v[1] == vt) {
2728 if (tri->
v[2] == vt) {
2738 bool allow_overlapping_edges)
2759 if (allow_overlapping_edges) {
2760#define LRT_TRI_SAME_POINT(tri, i, pt) \
2761 ((LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[0], pt->gloc[0]) && \
2762 LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[1], pt->gloc[1]) && \
2763 LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[2], pt->gloc[2])) || \
2764 (LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[0], pt->gloc[0]) && \
2765 LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[1], pt->gloc[1]) && \
2766 LRT_DOUBLE_CLOSE_ENOUGH(tri->v[i]->gloc[2], pt->gloc[2])))
2774#undef LRT_TRI_SAME_POINT
2781#define INTERSECT_SORT_MIN_TO_MAX_3(ia, ib, ic, lst) \
2783 lst[0] = LRT_MIN3_INDEX(ia, ib, ic); \
2784 lst[1] = (((ia <= ib && ib <= ic) || (ic <= ib && ib <= ia)) ? \
2786 (((ic <= ia && ia <= ib) || (ib < ia && ia <= ic)) ? 0 : 2)); \
2787 lst[2] = LRT_MAX3_INDEX(ia, ib, ic); \
2791#define INTERSECT_JUST_GREATER(is, order, num, index) \
2793 index = (num < is[order[0]] ? \
2795 (num < is[order[1]] ? order[1] : (num < is[order[2]] ? order[2] : -1))); \
2799#define INTERSECT_JUST_SMALLER(is, order, num, index) \
2801 index = (num > is[order[2]] ? \
2803 (num > is[order[1]] ? order[1] : (num > is[order[0]] ? order[0] : -1))); \
2806#define LRT_ISEC(index) (index == 0 ? isec_e1 : (index == 1 ? isec_e2 : isec_e3))
2807#define LRT_PARALLEL(index) (index == 0 ? para_e1 : (index == 1 ? para_e2 : para_e3))
2833 const double *override_camera_loc,
2834 const bool override_cam_is_persp,
2835 const bool allow_overlapping_edges,
2836 const double m_view_projection[4][4],
2837 const double camera_dir[3],
2838 const float cam_shift_x,
2839 const float cam_shift_y,
2843 double cross_ratios[3] = {0};
2845 int cross_v1 = -1, cross_v2 = -1;
2847 int isec_e1, isec_e2, isec_e3;
2849 bool para_e1, para_e2, para_e3;
2854 double view_vector[4];
2856 double dot_v1, dot_v2, dot_v1a, dot_v2a;
2858 double gloc[4], trans[4];
2861 double *LFBC =
e->v1->fbcoord, *RFBC =
e->v2->fbcoord, *FBC0 = tri->
v[0]->
fbcoord,
2865 if ((std::max({FBC0[0], FBC1[0], FBC2[0]}) < std::min(LFBC[0], RFBC[0])) ||
2866 (std::min({FBC0[0], FBC1[0], FBC2[0]}) > std::max(LFBC[0], RFBC[0])) ||
2867 (std::max({FBC0[1], FBC1[1], FBC2[1]}) < std::min(LFBC[1], RFBC[1])) ||
2868 (std::min({FBC0[1], FBC1[1], FBC2[1]}) > std::max(LFBC[1], RFBC[1])) ||
2869 (std::min({FBC0[3], FBC1[3], FBC2[3]}) > std::max(LFBC[3], RFBC[3])))
2892 if (override_cam_is_persp) {
2919 if (
fabs(dot_f) < FLT_EPSILON) {
2928 if (!isec_e1 && !isec_e2 && !isec_e3) {
2930 if ((!state_v1) && (!state_v2)) {
2937 dot_v1a =
fabs(dot_v1);
2938 if (dot_v1a < DBL_EPSILON) {
2942 dot_v2a =
fabs(dot_v2);
2943 if (dot_v2a < DBL_EPSILON) {
2947 if (dot_v1 - dot_v2 == 0) {
2950 else if (dot_v1 * dot_v2 <= 0) {
2951 cut = dot_v1a /
fabs(dot_v1 - dot_v2);
2954 cut =
fabs(dot_v2 + dot_v1) /
fabs(dot_v1 - dot_v2);
2955 cut = dot_v2a > dot_v1a ? 1 - cut : cut;
2959 if (override_cam_is_persp) {
2963 trans[0] -= cam_shift_x * 2;
2964 trans[1] -= cam_shift_y * 2;
2966 if (
fabs(
e->v1->fbcoord[0] -
e->v2->fbcoord[0]) >
fabs(
e->v1->fbcoord[1] -
e->v2->fbcoord[1]))
2968 cut =
ratiod(
e->v1->fbcoord[0],
e->v2->fbcoord[0], trans[0]);
2971 cut =
ratiod(
e->v1->fbcoord[1],
e->v2->fbcoord[1], trans[1]);
2975#define LRT_GUARD_NOT_FOUND \
2976 if (cross_v1 < 0 || cross_v2 < 0) { \
3069 if (cross_v1 >= 0 &&
LRT_ISEC(cross_v1)) {
3073 if (cross_v1 >= 0) {
3075 if (cross_v1 >= 0) {
3085 double dot_1f = dot_v1 * dot_f, dot_2f = dot_v2 * dot_f;
3088 if (dot_1f <= 0 && dot_2f <= 0 && (dot_v1 || dot_v2)) {
3089 *from = std::max(0.0, cross_ratios[cross_v1]);
3090 *to = std::min(1.0, cross_ratios[cross_v2]);
3096 if (dot_1f >= 0 && dot_2f <= 0 && (dot_v1 || dot_v2)) {
3097 *from = std::max(cut, cross_ratios[cross_v1]);
3098 *to = std::min(1.0, cross_ratios[cross_v2]);
3104 if (dot_1f <= 0 && dot_2f >= 0 && (dot_v1 || dot_v2)) {
3105 *from = std::max(0.0, cross_ratios[cross_v1]);
3106 *to = std::min(cut, cross_ratios[cross_v2]);
3117#undef INTERSECT_SORT_MIN_TO_MAX_3
3118#undef INTERSECT_JUST_GREATER
3119#undef INTERSECT_JUST_SMALLER
3129 if (
l->
v[0]->index == r->
v[0]->
index) {
3130 if (
l->
v[1]->index == r->
v[1]->
index ||
l->
v[1]->index == r->
v[2]->
index ||
3136 if (
l->
v[0]->index == r->
v[1]->
index) {
3137 if (
l->
v[1]->index == r->
v[0]->
index ||
l->
v[1]->index == r->
v[2]->
index ||
3143 if (
l->
v[0]->index == r->
v[2]->
index) {
3144 if (
l->
v[1]->index == r->
v[1]->
index ||
l->
v[1]->index == r->
v[0]->
index ||
3150 if (
l->
v[1]->index == r->
v[0]->
index) {
3151 if (
l->
v[2]->index == r->
v[1]->
index ||
l->
v[2]->index == r->
v[2]->
index ||
3157 if (
l->
v[1]->index == r->
v[1]->
index) {
3158 if (
l->
v[2]->index == r->
v[0]->
index ||
l->
v[2]->index == r->
v[2]->
index ||
3164 if (
l->
v[1]->index == r->
v[2]->
index) {
3165 if (
l->
v[2]->index == r->
v[1]->
index ||
l->
v[2]->index == r->
v[0]->
index ||
3179 if (
l->
v[0] == r->
v[0]) {
3182 if (
l->
v[0] == r->
v[1]) {
3185 if (
l->
v[0] == r->
v[2]) {
3188 if (
l->
v[1] == r->
v[0]) {
3191 if (
l->
v[1] == r->
v[1]) {
3194 if (
l->
v[1] == r->
v[2]) {
3197 if (
l->
v[2] == r->
v[0]) {
3200 if (
l->
v[2] == r->
v[1]) {
3203 if (
l->
v[2] == r->
v[2]) {
3214 double dir_v1[3], dir_v2[3];
3215 double dot_v1, dot_v2;
3224 if (dot_v1 * dot_v2 > 0 || (!dot_v1 && !dot_v2)) {
3228 dot_v1 =
fabs(dot_v1);
3229 dot_v2 =
fabs(dot_v2);
3254 double *
next = v1, *last =
nullptr;
3335 th->
array = new_array;
3340 isec_single->
tri1 = tri1;
3341 isec_single->
tri2 = tri2;
3343 std::swap(isec_single->
tri1, isec_single->
tri2);
3348#define LRT_ISECT_TRIANGLE_PER_THREAD 4096
3366 while (remaining > 0 && eln) {
3368 int added_count = std::min(remaining, remaining_this_eln);
3369 remaining -= added_count;
3370 if (remaining || added_count == remaining_this_eln) {
3406 for (
int i = 0; i < thread_count; i++) {
3437 double *G0 = tri->
v[0]->
gloc, *G1 = tri->
v[1]->
gloc, *G2 = tri->
v[2]->
gloc;
3440 for (
int i = 0; i < up_to; i++) {
3459 double *RG0 = testing_triangle->
v[0]->
gloc, *RG1 = testing_triangle->
v[1]->
gloc,
3460 *RG2 = testing_triangle->
v[2]->
gloc;
3463 if ((std::min({G0[2], G1[2], G2[2]}) > std::max({RG0[2], RG1[2], RG2[2]})) ||
3464 (std::max({G0[2], G1[2], G2[2]}) < std::min({RG0[2], RG1[2], RG2[2]})) ||
3465 (std::min({G0[0], G1[0], G2[0]}) > std::max({RG0[0], RG1[0], RG2[0]})) ||
3466 (std::max({G0[0], G1[0], G2[0]}) < std::min({RG0[0], RG1[0], RG2[0]})) ||
3467 (std::min({G0[1], G1[1], G2[1]}) > std::max({RG0[1], RG1[1], RG2[1]})) ||
3468 (std::max({G0[1], G1[1], G2[1]}) < std::min({RG0[1], RG1[1], RG2[1]})) ||
3476 double iv1[3], iv2[3];
3485 float direction[3] = {0, 0, 1};
3488 float obmat_no_scale[4][4];
3517 for (
int i = 0; i < 4; i++) {
3525 if (ld ==
nullptr) {
3550 if (ld ==
nullptr) {
3574 if (
G.debug_value == 4000) {
3575 printf(
"LRT: Destroyed render data.\n");
3608 if (!scene || !camera || !lc) {
3612 double clipping_offset = 0;
3616 clipping_offset = 0.0001;
3620 if (active_camera) {
3633 ld->
w = scene->r.xsch;
3634 ld->
h = scene->r.ysch;
3763 if (ld->
w > ld->
h) {
3764 sp_w = sp_h * ld->
w / ld->
h;
3767 sp_h = sp_w * ld->
h / ld->
w;
3772 double span_w = 1.0 / sp_w * 2.0;
3773 double span_h = 1.0 / sp_h * 2.0;
3788 for (row = 0; row < sp_h; row++) {
3793 ba->
l = span_w *
col - 1.0;
3794 ba->
r = (
col == sp_w - 1) ? 1.0 : (span_w * (
col + 1) - 1.0);
3795 ba->
u = 1.0 - span_h * row;
3796 ba->
b = (row == sp_h - 1) ? -1.0 : (1.0 - span_h * (row + 1));
3798 ba->
cx = (ba->
l + ba->
r) / 2;
3799 ba->
cy = (ba->
u + ba->
b) / 2;
3844 if (ba[1].u > tba->
b && ba[1].
b < tba->u) {
3848 if (ba[2].u > tba->
b && ba[2].
b < tba->u) {
3855 if (ba[0].u > tba->
b && ba[0].
b < tba->u) {
3859 if (ba[3].u > tba->
b && ba[3].
b < tba->u) {
3866 if (ba[0].r > tba->
l && ba[0].
l < tba->r) {
3870 if (ba[1].r > tba->
l && ba[1].
l < tba->r) {
3877 if (ba[2].r > tba->
l && ba[2].
l < tba->r) {
3881 if (ba[3].r > tba->
l && ba[3].
l < tba->r) {
3893 next_lip = lip2->
next;
3897 if (ba[1].u > tba->
b && ba[1].
b < tba->u) {
3900 if (ba[2].u > tba->
b && ba[2].
b < tba->u) {
3910 next_lip = lip2->
next;
3914 if (ba[0].u > tba->
b && ba[0].
b < tba->u) {
3917 if (ba[3].u > tba->
b && ba[3].
b < tba->u) {
3927 next_lip = lip2->
next;
3931 if (ba[0].r > tba->
l && ba[0].
l < tba->r) {
3934 if (ba[1].r > tba->
l && ba[1].
l < tba->r) {
3944 next_lip = lip2->
next;
3948 if (ba[2].r > tba->
l && ba[2].
l < tba->r) {
3951 if (ba[3].r > tba->
l && ba[3].
l < tba->r) {
3969 for (
int i = 0; i < 4; i++) {
4002 for (
int i = 0; i < total_tile_initial; i++) {
4013 int recursive_level)
4021 ba[0].
cx = (ba[0].
l + ba[0].
r) / 2;
4022 ba[0].
cy = (ba[0].
u + ba[0].
b) / 2;
4028 ba[1].
cx = (ba[1].
l + ba[1].
r) / 2;
4029 ba[1].
cy = (ba[1].
u + ba[1].
b) / 2;
4035 ba[2].
cx = (ba[2].
l + ba[2].
r) / 2;
4036 ba[2].
cy = (ba[2].
u + ba[2].
b) / 2;
4042 ba[3].
cx = (ba[3].
l + ba[3].
r) / 2;
4043 ba[3].
cy = (ba[3].
u + ba[3].
b) / 2;
4046 for (
int i = 0; i < 4; i++) {
4069 ld, &ba[0], tri,
b, 0, recursive_level + 1,
false,
nullptr);
4073 ld, &ba[1], tri,
b, 0, recursive_level + 1,
false,
nullptr);
4077 ld, &ba[2], tri,
b, 0, recursive_level + 1,
false,
nullptr);
4081 ld, &ba[3], tri,
b, 0, recursive_level + 1,
false,
nullptr);
4096 double converted[4];
4099 if (((converted[0] = ba->
l) > std::max(
l[0], r[0])) ||
4100 ((converted[1] = ba->
r) < std::min(
l[0], r[0])) ||
4101 ((converted[2] = ba->
b) > std::max(
l[1], r[1])) ||
4102 ((converted[3] = ba->
u) < std::min(
l[1], r[1])))
4110 c1 = dx * (converted[2] -
l[1]) - dy * (converted[0] -
l[0]);
4113 c1 = dx * (converted[2] -
l[1]) - dy * (converted[1] -
l[0]);
4119 c1 = dx * (converted[3] -
l[1]) - dy * (converted[0] -
l[0]);
4125 c1 = dx * (converted[3] -
l[1]) - dy * (converted[1] -
l[0]);
4137 bool *r_triangle_vert_inside)
4139 double p1[2], p2[2], p3[2], p4[2];
4142 p3[0] = p1[0] = ba->
l;
4143 p2[1] = p1[1] = ba->
b;
4144 p2[0] = p4[0] = ba->
r;
4145 p3[1] = p4[1] = ba->
u;
4147 if ((FBC1[0] >= p1[0] && FBC1[0] <= p2[0] && FBC1[1] >= p1[1] && FBC1[1] <= p3[1]) ||
4148 (FBC2[0] >= p1[0] && FBC2[0] <= p2[0] && FBC2[1] >= p1[1] && FBC2[1] <= p3[1]) ||
4149 (FBC3[0] >= p1[0] && FBC3[0] <= p2[0] && FBC3[1] >= p1[1] && FBC3[1] <= p3[1]))
4151 *r_triangle_vert_inside =
true;
4155 *r_triangle_vert_inside =
false;
4192 int recursive_level,
4193 bool do_intersection,
4196 bool triangle_vert_inside;
4203 if (old_ba->
child) {
4206 double *B1 = l_r_u_b;
4215 for (
int iba = 0; iba < 4; iba++) {
4218 ld, &old_ba->
child[iba], tri, B1, recursive, recursive_level + 1, do_intersection, th);
4236 if (triangle_vert_inside) {
4252 if (recursive_level < ld->qtree.recursive_level &&
4255 if (!old_ba->
child) {
4274 ld, root_ba, tri, l_r_u_b, recursive, recursive_level, do_intersection, th);
4287 if (recursive && ba->
child) {
4288 for (
int i = 0; i < 4; i++) {
4306 if (root_ba->
child ==
nullptr) {
4311 ld,
e->v1->fbcoord,
e->v2->fbcoord, &root_ba->
child[0]))
4316 ld,
e->v1->fbcoord,
e->v2->fbcoord, &root_ba->
child[1]))
4321 ld,
e->v1->fbcoord,
e->v2->fbcoord, &root_ba->
child[2]))
4326 ld,
e->v1->fbcoord,
e->v2->fbcoord, &root_ba->
child[3]))
4335 if (root_ba->
child) {
4336 for (
int i = 0; i < 4; i++) {
4362 int r1, r2, c1, c2, row,
col;
4364 for (row = r1; row != r2 + 1; row++) {
4379 for (
int i = 0; i < 4; i++) {
4389 int usable_count = 0;
4392 if (
e->min_occ > max_occlusion) {
4398 if (!usable_count) {
4409 if (
e->min_occ > max_occlusion) {
4412 new_array[new_i] =
e;
4437 if (!tri->
v[0] || !tri->
v[1] || !tri->
v[2]) {
4446 if (
b[0] > 1 ||
b[1] < -1 ||
b[2] > 1 ||
b[3] < -1) {
4450 (*colbegin) =
int((
b[0] + 1.0) / sp_w);
4451 (*colend) =
int((
b[1] + 1.0) / sp_w);
4461 if ((*colbegin) < 0) {
4464 if ((*rowbegin) < 0) {
4477 if (!
e->v1 || !
e->v2) {
4481 if (
e->v1->fbcoord[0] !=
e->v1->fbcoord[0] ||
e->v2->fbcoord[0] !=
e->v2->fbcoord[0]) {
4485 b[0] = std::min(
e->v1->fbcoord[0],
e->v2->fbcoord[0]);
4486 b[1] = std::max(
e->v1->fbcoord[0],
e->v2->fbcoord[0]);
4487 b[2] = std::min(
e->v1->fbcoord[1],
e->v2->fbcoord[1]);
4488 b[3] = std::max(
e->v1->fbcoord[1],
e->v2->fbcoord[1]);
4490 if (
b[0] > 1 ||
b[1] < -1 ||
b[2] > 1 ||
b[3] < -1) {
4494 (*colbegin) =
int((
b[0] + 1.0) / sp_w);
4495 (*colend) =
int((
b[1] + 1.0) / sp_w);
4500 if ((*rowend) < (*rowbegin)) {
4504 if ((*colend) < (*colbegin)) {
4525 col =
int((x + 1.0) / sp_w);
4548 int c =
int((x + 1.0) / sp_w);
4564 while (iba->
child) {
4567 iba = &iba->
child[0];
4570 iba = &iba->
child[3];
4575 iba = &iba->
child[1];
4578 iba = &iba->
child[2];
4606 for (
int ei = index_start; ei < index_end; ei++) {
4615 for (co = x1; co <= x2; co++) {
4616 for (r = y1; r <= y2; r++) {
4639 int total_lines = 0;
4643 if (
G.debug_value == 4000) {
4644 printf(
"Thread %d isec generated %d lines.\n", i, th->
current);
4678 for (
int j = 0; j < th->
current; j++) {
4701 v2->fbcoord[2] = ZMin * ZMax / (ZMax -
fabs(
v2->fbcoord[2]) * (ZMax - ZMin));
4707 e->edge_identifier = (
uint64_t(
e->t1->target_reference) << 32) |
e->t2->target_reference;
4709 e->intersection_mask = (is->tri1->intersection_mask | is->tri2->intersection_mask);
4721 if (
e->t1->intersection_priority >
e->t2->intersection_priority) {
4722 e->object_ref = ob1;
4724 else if (
e->t1->intersection_priority <
e->t2->intersection_priority) {
4725 e->object_ref = ob2;
4730 e->object_ref = ob1;
4746 if (
G.debug_value == 4000) {
4769 if (
G.debug_value == 4000) {
4771 printf(
"Line art intersection time: %f\n", t_elapsed);
4779 double data[2] = {fbcoord1[0], fbcoord1[1]};
4780 double LU[2] = {-1, 1}, RU[2] = {1, 1},
LB[2] = {-1, -1},
RB[2] = {1, -1};
4781 double r = 1, sr = 1;
4784 if (data[0] > -1 && data[0] < 1 && data[1] > -1 && data[1] < 1) {
4816 double rx, ry, ux, uy, lx, ly, bx, by;
4821 if (positive_x > 0) {
4823 ry = y + k * (rx -
x);
4826 if (positive_y > 0) {
4828 ux = x + (uy -
y) / k;
4829 r1 =
ratiod(fbcoord1[0], fbcoord2[0], rx);
4830 r2 =
ratiod(fbcoord1[0], fbcoord2[0], ux);
4831 if (std::min(r1, r2) > 1) {
4839 if (ba->
u >= ry && ba->
b < ry) {
4850 if (ba->
r >= ux && ba->
l < ux) {
4859 else if (positive_y < 0) {
4861 bx = x + (by -
y) / k;
4862 r1 =
ratiod(fbcoord1[0], fbcoord2[0], rx);
4863 r2 =
ratiod(fbcoord1[0], fbcoord2[0], bx);
4864 if (std::min(r1, r2) > 1) {
4870 if (ba->
u >= ry && ba->
b < ry) {
4880 if (ba->
r >= bx && ba->
l < bx) {
4890 r1 =
ratiod(fbcoord1[0], fbcoord2[0],
self->r);
4896 if (ba->
u >= y && ba->
b < y) {
4906 else if (positive_x < 0) {
4908 ly = y + k * (lx -
x);
4911 if (positive_y > 0) {
4913 ux = x + (uy -
y) / k;
4914 r1 =
ratiod(fbcoord1[0], fbcoord2[0], lx);
4915 r2 =
ratiod(fbcoord1[0], fbcoord2[0], ux);
4916 if (std::min(r1, r2) > 1) {
4922 if (ba->
u >= ly && ba->
b < ly) {
4932 if (ba->
r >= ux && ba->
l < ux) {
4942 else if (positive_y < 0) {
4944 bx = x + (by -
y) / k;
4945 r1 =
ratiod(fbcoord1[0], fbcoord2[0], lx);
4946 r2 =
ratiod(fbcoord1[0], fbcoord2[0], bx);
4947 if (std::min(r1, r2) > 1) {
4953 if (ba->
u >= ly && ba->
b < ly) {
4963 if (ba->
r >= bx && ba->
l < bx) {
4973 r1 =
ratiod(fbcoord1[0], fbcoord2[0],
self->l);
4979 if (ba->
u >= y && ba->
b < y) {
4989 if (positive_y > 0) {
4990 r1 =
ratiod(fbcoord1[1], fbcoord2[1],
self->u);
4996 if (ba->
r > x && ba->
l <= x) {
5003 else if (positive_y < 0) {
5004 r1 =
ratiod(fbcoord1[1], fbcoord2[1],
self->b);
5010 if (ba->
r > x && ba->
l <= x) {
5028 bool enable_stroke_depth_offset)
5032 int intersections_only = 0;
5033 Object *lineart_camera =
nullptr;
5036 if (
G.debug_value == 4000) {
5040 bool use_render_camera_override =
false;
5051 if (render && render->camera_override) {
5053 use_render_camera_override =
true;
5055 if (!lineart_camera) {
5057 if (!scene->camera) {
5060 lineart_camera = scene->camera;
5067 *cached_result = lc;
5073 use_render_camera_override ? lineart_camera : scene->camera,
5109 if (shadow_generated) {
5157 if (!intersections_only) {
5219 if (
G.debug_value == 4000) {
5223 printf(
"Line art total time: %lf\n", t_elapsed);
5238 const int8_t source_type,
5241 const int level_start,
5242 const int level_end,
5245 const uchar mask_switches,
5246 const uchar material_mask_bits,
5247 const uchar intersection_mask,
5248 const float thickness,
5249 const float opacity,
5250 const uchar shadow_selection,
5251 const uchar silhouette_mode,
5252 const char *source_vgname,
5254 const int modifier_flags,
5255 const int modifier_calculation_flags)
5257 if (
G.debug_value == 4000) {
5258 printf(
"Line Art v3: Generating...\n");
5261 if (cache ==
nullptr) {
5262 if (
G.debug_value == 4000) {
5263 printf(
"nullptr Lineart cache!\n");
5268 Object *orig_ob =
nullptr;
5272 if (!source_object) {
5279 if (!source_collection) {
5296 int total_point_count = 0;
5297 int stroke_count = 0;
5303 if (!(ec->type & (edge_types & enabled_types))) {
5306 if (ec->level > level_end || ec->level < level_start) {
5309 if (orig_ob && orig_ob != ec->object_ref) {
5312 if (orig_col && ec->object_ref) {
5326 if (ec->material_mask_bits != material_mask_bits) {
5331 if (!(ec->material_mask_bits & material_mask_bits)) {
5338 if (ec->intersection_mask != intersection_mask) {
5343 if ((intersection_mask) && !(ec->intersection_mask & intersection_mask)) {
5348 if (shadow_selection) {
5372 bool is_silhouette =
false;
5374 if (!ec->silhouette_backdrop) {
5375 is_silhouette =
true;
5379 is_silhouette =
true;
5383 if ((!orig_ob) && (!ec->silhouette_backdrop)) {
5384 is_silhouette =
true;
5389 ec->silhouette_backdrop != ec->object_ref)
5391 is_silhouette =
true;
5394 if (inverse_silhouette) {
5395 is_silhouette = !is_silhouette;
5397 if (!is_silhouette) {
5410 total_point_count +=
count;
5416 if (!total_point_count || !stroke_count) {
5427 "radius", AttrDomain::Point);
5430 "opacity", AttrDomain::Point);
5433 "material_index", AttrDomain::Curve);
5439 vgroup_weights = attributes.lookup_or_add_for_write_span<
float>(vgname, AttrDomain::Point);
5442 int up_to_point = 0;
5447 int src_deform_group = -1;
5448 Mesh *src_mesh =
nullptr;
5449 if (source_vgname && vgroup_weights) {
5453 src_dvert = src_mesh->deform_verts_for_write().data();
5460 int point_i = i + up_to_point;
5462 point_radii.
span[point_i] = thickness / 2.0f;
5463 point_opacities.span[point_i] = opacity;
5465 if (src_deform_group >= 0) {
5467 vindex = eci->index;
5473 vgroup_weights.
span[point_i] = invert_input ? (1 - mdw->
weight) : mdw->
weight;
5476 offsets[chain_i] = up_to_point;
5477 stroke_materials.span[chain_i] =
max_ii(mat_nr, 0);
5483 "cyclic", AttrDomain::Curve);
5484 stroke_cyclic.
span.fill(
false);
5488 point_opacities.finish();
5489 stroke_materials.finish();
5493 std::array<blender::bke::GeometrySet, 2> geometry_sets{
5501 if (
G.debug_value == 4000) {
5502 printf(
"LRT: Generated %d strokes.\n", stroke_count);
Camera data-block and utility functions.
float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
bool BKE_collection_has_object_recursive_instanced(Collection *collection, Object *ob)
bool BKE_collection_has_object(Collection *collection, const Object *ob)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
int CustomData_get_active_layer_index(const CustomData *data, eCustomDataType type)
Low-level operations for grease pencil.
void BKE_id_free(Main *bmain, void *idv)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
struct Material * BKE_object_material_get_eval(struct Object *ob, short act)
Mesh * BKE_mesh_new_from_object(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers, bool preserve_origindex)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
void BKE_boundbox_init_from_minmax(BoundBox *bb, const float min[3], const float max[3])
int BKE_object_visibility(const Object *ob, int dag_eval_mode)
int BKE_render_num_threads(const RenderData *r)
bool BKE_scene_camera_switch_update(Scene *scene)
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
MINLINE double ratiod(double min, double max, double pos)
MINLINE int max_ii(int a, int b)
int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
#define ISECT_LINE_LINE_NONE
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
void mul_v4_m4v3_db(double r[4], const double mat[4][4], const double vec[3])
void mul_v3_m4v3_db(double r[3], const double mat[4][4], const double vec[3])
void mul_m4db_m4db_m4fl(double R[4][4], const double A[4][4], const float B[4][4])
void unit_m4_db(double m[4][4])
void copy_m4d_m4(double m1[4][4], const float m2[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_v3_mat3_m4v3_db(double r[3], const double mat[4][4], const double vec[3])
void transpose_m4(float R[4][4])
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void copy_m4_m4_db(double m1[4][4], const double m2[4][4])
float focallength_to_fov(float focal_length, float sensor)
MINLINE double normalize_v3_db(double n[3])
void interp_v3_v3v3_db(double target[3], const double a[3], const double b[3], double t)
MINLINE void mul_v3db_db(double r[3], double f)
MINLINE void add_v3_v3_db(double r[3], const double a[3])
MINLINE double dot_v3v3_db(const double a[3], const double b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3db_v3fl(double r[3], const float a[3])
MINLINE void cross_v3_v3v3_db(double r[3], const double a[3], const double b[3])
MINLINE void copy_v3_v3_db(double r[3], const double a[3])
void interp_v2_v2v2_db(double target[2], const double a[2], const double b[2], double t)
MINLINE float normalize_v3(float n[3])
MINLINE void sub_v3_v3v3_db(double r[3], const double a[3], const double b[3])
MINLINE void sub_v2_v2v2_db(double r[2], const double a[2], const double b[2])
void BLI_task_pool_work_and_wait(TaskPool *pool)
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
void BLI_spin_init(SpinLock *spin)
void BLI_spin_unlock(SpinLock *spin)
void BLI_spin_lock(SpinLock *spin)
void BLI_spin_end(SpinLock *spin)
Platform independent time functions.
double BLI_time_now_seconds(void)
typedef double(DMatrix)[4][4]
#define DEG_OBJECT_ITER_BEGIN(settings_, instance_)
#define DEG_OBJECT_ITER_END
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY
@ DEG_ITER_OBJECT_FLAG_VISIBLE
@ DEG_ITER_OBJECT_FLAG_DUPLI
@ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_VIEWPORT
@ COLLECTION_LRT_INTERSECTION_ONLY
@ COLLECTION_LRT_FORCE_INTERSECTION
@ COLLECTION_LRT_OCCLUSION_ONLY
@ COLLECTION_LRT_NO_INTERSECTION
@ COLLECTION_LRT_USE_INTERSECTION_MASK
@ COLLECTION_LRT_USE_INTERSECTION_PRIORITY
@ MOD_LINEART_EDGE_FLAG_PROJECTED_SHADOW
@ MOD_LINEART_EDGE_FLAG_CONTOUR
@ MOD_LINEART_EDGE_FLAG_LIGHT_CONTOUR
@ MOD_LINEART_EDGE_FLAG_SHADOW_FACING_LIGHT
@ MOD_LINEART_EDGE_FLAG_INTERSECTION
@ MOD_LINEART_EDGE_FLAG_INHIBIT
@ MOD_LINEART_EDGE_FLAG_CHAIN_PICKED
@ MOD_LINEART_EDGE_FLAG_CREASE
@ MOD_LINEART_EDGE_FLAG_CONTOUR_SECONDARY
@ MOD_LINEART_EDGE_FLAG_NEXT_IS_DUPLICATION
@ MOD_LINEART_EDGE_FLAG_MATERIAL
@ MOD_LINEART_EDGE_FLAG_EDGE_MARK
@ MOD_LINEART_EDGE_FLAG_LOOSE
@ MOD_LINEART_FILTER_FACE_MARK
@ MOD_LINEART_FILTER_FACE_MARK_BOUNDARIES
@ MOD_LINEART_USE_CREASE_ON_SMOOTH_SURFACES
@ MOD_LINEART_USE_IMAGE_BOUNDARY_TRIMMING
@ MOD_LINEART_LOOSE_AS_CONTOUR
@ MOD_LINEART_CHAIN_PRESERVE_DETAILS
@ MOD_LINEART_USE_BACK_FACE_CULLING
@ MOD_LINEART_CHAIN_LOOSE_EDGES
@ MOD_LINEART_USE_CUSTOM_CAMERA
@ MOD_LINEART_USE_CREASE_ON_SHARP_EDGES
@ MOD_LINEART_INVERT_SOURCE_VGROUP
@ MOD_LINEART_EVERYTHING_AS_CONTOUR
@ MOD_LINEART_ALLOW_DUPLI_OBJECTS
@ MOD_LINEART_CHAIN_GEOMETRY_SPACE
@ MOD_LINEART_FILTER_FACE_MARK_KEEP_CONTOUR
@ MOD_LINEART_INTERSECTION_AS_CONTOUR
@ MOD_LINEART_ALLOW_OVERLAP_EDGE_TYPES
@ MOD_LINEART_ALLOW_OVERLAPPING_EDGES
@ MOD_LINEART_ALLOW_CLIPPING_BOUNDARIES
@ MOD_LINEART_FILTER_FACE_MARK_INVERT
@ LRT_MATERIAL_CUSTOM_INTERSECTION_PRIORITY
@ LRT_MATERIAL_MASK_ENABLED
@ LINEART_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES
@ LINEART_SHADOW_FILTER_SHADED
@ LINEART_SHADOW_FILTER_ILLUMINATED
@ MOD_LINEART_MATERIAL_MASK_ENABLE
@ MOD_LINEART_INTERSECTION_MATCH
@ MOD_LINEART_MATERIAL_MASK_MATCH
@ LINEART_SILHOUETTE_FILTER_INDIVIDUAL
@ MOD_LINEART_INVERT_SILHOUETTE_FILTER
@ MOD_LINEART_OFFSET_TOWARDS_CUSTOM_CAMERA
@ MOD_LINEART_INVERT_COLLECTION
@ LINEART_SOURCE_COLLECTION
@ OBJECT_LRT_OWN_INTERSECTION_PRIORITY
@ OBJECT_LRT_NO_INTERSECTION
@ OBJECT_LRT_OCCLUSION_ONLY
@ OBJECT_LRT_INTERSECTION_ONLY
@ OBJECT_LRT_FORCE_INTERSECTION
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define LRT_TILE_EDGE_COUNT_INITIAL
#define LRT_DOUBLE_CLOSE_ENOUGH(a, b)
#define LRT_SHADOW_MASK_INHIBITED
#define LRT_SHADOW_MASK_UNDEFINED
#define LRT_OBINDEX_LOWER
BLI_INLINE int lineart_intersect_seg_seg(const double a1[2], const double a2[2], const double b1[2], const double b2[2], double *r_ratio, bool *r_aligned)
#define LRT_OBINDEX_SHIFT
#define LRT_SHADOW_MASK_ILLUMINATED_SHAPE
#define LRT_LIGHT_CONTOUR_TARGET
#define LRT_SHADOW_MASK_ENCLOSED_SHAPE
#define LRT_SHADOW_TEST_SHAPE_BITS
#define LRT_OBINDEX_HIGHER
@ LRT_TILE_RECURSIVE_PERSPECTIVE
@ LRT_TILE_RECURSIVE_ORTHO
#define LRT_SHADOW_MASK_ILLUMINATED
#define LRT_TILE_SPLITTING_TRIANGLE_LIMIT
@ LRT_TRIANGLE_NO_INTERSECTION
@ LRT_TRIANGLE_MAT_BACK_FACE_CULLING
@ LRT_TRIANGLE_INTERSECTION_ONLY
@ LRT_TRIANGLE_FORCE_INTERSECTION
#define LRT_THREAD_EDGE_COUNT
#define LRT_SHADOW_MASK_SHADED
@ LRT_ELEMENT_NO_INTERSECTION
@ LRT_ELEMENT_BORDER_ONLY
@ LRT_ELEMENT_INTERSECTION_DATA
@ LRT_ELEMENT_IS_ADDITIONAL
struct LineartTriangle LineartTriangle
#define LRT_EDGE_IDENTIFIER(obi, e)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool is_empty() const
void append(const T &value)
IndexRange index_range() const
void reserve(const int64_t min_capacity)
MutableSpan< float3 > positions_for_write()
MutableAttributeAccessor attributes_for_write()
void fill_curve_types(CurveType type)
MutableSpan< int > offsets_for_write()
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
void tag_topology_changed()
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
BLI_INLINE float fb(float length, float L)
void MOD_lineart_chain_connect(LineartData *ld)
void MOD_lineart_chain_split_for_fixed_occlusion(LineartData *ld)
void MOD_lineart_chain_clip_at_border(LineartData *ld)
int MOD_lineart_chain_count(const LineartEdgeChain *ec)
void MOD_lineart_finalize_chains(LineartData *ld)
void MOD_lineart_chain_find_silhouette_backdrop_objects(LineartData *ld)
void MOD_lineart_chain_feature_lines(LineartData *ld)
void MOD_lineart_chain_clear_picked_flag(LineartCache *lc)
void MOD_lineart_smooth_chains(LineartData *ld, float tolerance)
void MOD_lineart_chain_split_angle(LineartData *ld, float angle_threshold_rad)
void MOD_lineart_chain_offset_towards_camera(LineartData *ld, float dist, bool use_custom_camera)
static void lineart_bounding_area_line_add(LineartBoundingArea *ba, LineartEdge *e)
LineartCache * MOD_lineart_init_cache()
static void lineart_bounding_areas_connect_recursive(LineartData *ld, LineartBoundingArea *root)
void lineart_main_load_geometries(Depsgraph *depsgraph, Scene *scene, Object *camera, LineartData *ld, bool allow_duplicates, bool do_shadow_casting, ListBase *shadow_elns, blender::Set< const Object * > *included_objects)
static int lineart_triangle_size_get(LineartData *ld)
static LineartEdgeSegment * lineart_give_segment(LineartData *ld)
void lineart_main_occlusion_begin(LineartData *ld)
static void lineart_add_triangles_worker(TaskPool *__restrict, LineartIsecThread *th)
#define INTERSECT_JUST_SMALLER(is, order, num, index)
static void lineart_init_isec_thread(LineartIsecData *d, LineartData *ld, int thread_count)
static LineartBoundingArea * lineart_get_bounding_area(LineartData *ld, double x, double y)
#define LRT_MESH_EDGE_TYPES_COUNT
#define RELINK_EDGE(e_num, new_tri)
static void lineart_destroy_isec_thread(LineartIsecData *d)
static void lineart_occlusion_worker(TaskPool *__restrict, LineartRenderTaskInfo *rti)
static bool lineart_triangle_intersect_math(LineartTriangle *tri, LineartTriangle *t2, double *v1, double *v2)
static bool lineart_bounding_area_triangle_intersect(LineartData *fb, LineartTriangle *tri, LineartBoundingArea *ba, bool *r_triangle_vert_inside)
void lineart_main_discard_out_of_frame_edges(LineartData *ld)
void lineart_main_get_view_vector(LineartData *ld)
void lineart_main_link_lines(LineartData *ld)
LineartBoundingArea * MOD_lineart_get_parent_bounding_area(LineartData *ld, double x, double y)
bool lineart_edge_from_triangle(const LineartTriangle *tri, const LineartEdge *e, bool allow_overlapping_edges)
static bool lineart_edge_match(LineartTriangle *tri, LineartEdge *e, int v1, int v2)
static void lineart_create_edges_from_isec_data(LineartIsecData *d)
static LineartVert * lineart_triangle_share_point(const LineartTriangle *l, const LineartTriangle *r)
static void lineart_sort_adjacent_items(LineartAdjacentEdge *ai, int length)
static bool lineart_bounding_area_edge_intersect(LineartData *, const double l[2], const double r[2], LineartBoundingArea *ba)
static void lineart_add_isec_thread(LineartIsecThread *th, const double *v1, const double *v2, LineartTriangle *tri1, LineartTriangle *tri2)
static bool lineart_triangle_2v_intersection_math(LineartVert *v1, LineartVert *v2, LineartTriangle *tri, const double *last, double *rv)
void lineart_main_bounding_areas_connect_post(LineartData *ld)
static const int LRT_MESH_EDGE_TYPES[]
static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartData *la_data, ListBase *shadow_elns)
static void lineart_edge_neighbor_init_task(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
#define LRT_VERT_OUT_OF_BOUND(v)
static void lineart_destroy_render_data(LineartData *ld)
struct LineartChainWriteInfo LineartChainWriteInfo
void lineart_main_add_triangles(LineartData *ld)
LineartBoundingArea * lineart_bounding_area_next(LineartBoundingArea *self, double *fbcoord1, double *fbcoord2, double x, double y, double k, int positive_x, int positive_y, double *next_x, double *next_y)
static LineartElementLinkNode * lineart_memory_get_vert_space(LineartData *ld)
static bool lineart_triangle_share_edge(const LineartTriangle *l, const LineartTriangle *r)
static uchar lineart_intersection_mask_check(Collection *c, Object *ob)
void lineart_add_edge_to_array(LineartPendingEdges *pe, LineartEdge *e)
static bool lineart_point_inside_triangle3d(double v[3], double v0[3], double v1[3], double v2[3])
static int lineart_occlusion_make_task_info(LineartData *ld, LineartRenderTaskInfo *rti)
#define LRT_CULL_DECIDE_INSIDE
void lineart_main_clear_linked_edges(LineartData *ld)
static void lineart_triangle_adjacent_assign(LineartTriangle *tri, LineartTriangleAdjacent *tri_adj, LineartEdge *e)
static void lineart_bounding_area_triangle_reallocate(LineartBoundingArea *ba)
static void lineart_free_bounding_area_memories(LineartData *ld)
static bool lineart_triangle_edge_image_space_occlusion(const LineartTriangle *tri, const LineartEdge *e, const double *override_camera_loc, const bool override_cam_is_persp, const bool allow_overlapping_edges, const double m_view_projection[4][4], const double camera_dir[3], const float cam_shift_x, const float cam_shift_y, double *from, double *to)
static int lineart_edge_type_duplication_count(int eflag)
void lineart_main_cull_triangles(LineartData *ld, bool clip_far)
static LineartTriangle * lineart_triangle_from_index(LineartData *ld, LineartTriangle *rt_array, int index)
void MOD_lineart_clear_cache(LineartCache **lc)
static void lineart_bounding_area_split(LineartData *ld, LineartBoundingArea *root, int recursive_level)
void lineart_main_bounding_area_make_initial(LineartData *ld)
static void lineart_add_edge_to_array_thread(LineartObjectInfo *obi, LineartEdge *e)
#define LRT_ISECT_TRIANGLE_PER_THREAD
static void lineart_load_tri_task(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void lineart_triangle_post(LineartTriangle *tri, LineartTriangle *orig)
static bool lineart_get_triangle_bounding_areas(LineartData *ld, LineartTriangle *tri, int *rowbegin, int *rowend, int *colbegin, int *colend)
static void lineart_object_load_single_instance(LineartData *ld, Depsgraph *depsgraph, Scene *scene, Object *ob, Object *ref_ob, const float use_mat[4][4], bool is_render, LineartObjectLoadTaskInfo *olti, int thread_count, int obindex)
static void lineart_triangle_intersect_in_bounding_area(LineartTriangle *tri, LineartBoundingArea *ba, LineartIsecThread *th, int up_to)
static void lineart_triangle_set_cull_flag(LineartTriangle *tri, uchar flag)
static LineartElementLinkNode * lineart_memory_get_triangle_space(LineartData *ld)
static void lineart_finalize_object_edge_array(LineartPendingEdges *pe, LineartObjectInfo *obi)
LineartBoundingArea * MOD_lineart_get_bounding_area(LineartData *ld, double x, double y)
void lineart_main_free_adjacent_data(LineartData *ld)
static void lineart_occlusion_single_line(LineartData *ld, LineartEdge *e, int thread_id)
static void lineart_triangle_cull_single(LineartData *ld, LineartTriangle *tri, int in0, int in1, int in2, double cam_pos[3], double view_dir[3], bool allow_boundaries, double m_view_projection[4][4], Object *ob, int *r_v_count, int *r_e_count, int *r_t_count, LineartElementLinkNode *v_eln, LineartElementLinkNode *e_eln, LineartElementLinkNode *t_eln)
static void lineart_free_bounding_area_memory(LineartBoundingArea *ba, bool recursive)
#define REMOVE_TRIANGLE_EDGE
static bool lineart_point_inside_triangle(const double v[2], const double v0[2], const double v1[2], const double v2[2])
static void lineart_end_bounding_area_recursive(LineartBoundingArea *ba)
static LineartPointTri lineart_point_triangle_relation(double v[2], double v0[2], double v1[2], double v2[2])
static void lineart_bounding_area_link_edge(LineartData *ld, LineartBoundingArea *root_ba, LineartEdge *e)
#define LRT_PARALLEL(index)
static LineartData * lineart_create_render_buffer_v3(Scene *scene, GreasePencilLineartModifierData *lmd, Object *camera, Object *active_camera, LineartCache *lc)
static void lineart_geometry_load_assign_thread(LineartObjectLoadTaskInfo *olti_list, LineartObjectInfo *obi, int thread_count, int this_face_count)
static void lineart_object_load_worker(TaskPool *__restrict, LineartObjectLoadTaskInfo *olti)
void MOD_lineart_destroy_render_data_v3(GreasePencilLineartModifierData *lmd)
void lineart_destroy_render_data_keep_init(LineartData *ld)
static int lineart_point_on_line_segment(double v[2], double v0[2], double v1[2])
static uchar lineart_intersection_priority_check(Collection *c, Object *ob)
static void lineart_mvert_transform_task(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
#define INTERSECT_JUST_GREATER(is, order, num, index)
static void lineart_identify_corner_tri_feature_edges(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
static bool lineart_schedule_new_triangle_task(LineartIsecThread *th)
static void lineart_discard_duplicated_edges(LineartEdge *old_e)
static void feat_data_sum_reduce(const void *__restrict, void *__restrict chunk_join, void *__restrict chunk)
#define LRT_TRI_SAME_POINT(tri, i, pt)
static void lineart_clear_linked_edges_recursive(LineartData *ld, LineartBoundingArea *root_ba)
void lineart_edge_cut(LineartData *ld, LineartEdge *e, double start, double end, uchar material_mask_bits, uchar mat_occlusion, uint32_t shadow_bits)
static int lineart_usage_check(Collection *c, Object *ob, bool is_render)
static bool lineart_get_edge_bounding_areas(LineartData *ld, LineartEdge *e, int *rowbegin, int *rowend, int *colbegin, int *colend)
static void lineart_discard_segment(LineartData *ld, LineartEdgeSegment *es)
void lineart_main_perspective_division(LineartData *ld)
void MOD_lineart_gpencil_generate_v3(const LineartCache *cache, const blender::float4x4 &inverse_mat, Depsgraph *depsgraph, blender::bke::greasepencil::Drawing &drawing, const int8_t source_type, Object *source_object, Collection *source_collection, const int level_start, const int level_end, const int mat_nr, const int16_t edge_types, const uchar mask_switches, const uchar material_mask_bits, const uchar intersection_mask, const float thickness, const float opacity, const uchar shadow_selection, const uchar silhouette_mode, const char *source_vgname, const char *vgname, const int modifier_flags, const int modifier_calculation_flags)
static LineartElementLinkNode * lineart_memory_get_edge_space(LineartData *ld)
LineartBoundingArea * lineart_edge_first_bounding_area(LineartData *ld, double *fbcoord1, double *fbcoord2)
static LineartEdgeNeighbor * lineart_build_edge_neighbor(Mesh *mesh, int total_edges)
static void lineart_main_remove_unused_lines_from_tiles(LineartData *ld)
static void lineart_bounding_areas_connect_new(LineartData *ld, LineartBoundingArea *root)
#define INTERSECT_SORT_MIN_TO_MAX_3(ia, ib, ic, lst)
void lineart_finalize_object_edge_array_reserve(LineartPendingEdges *pe, int count)
#define SELECT_EDGE(e_num, v1_link, v2_link, new_tri)
static void lineart_main_remove_unused_lines_recursive(LineartBoundingArea *ba, uint8_t max_occlusion)
BLI_INLINE bool lineart_occlusion_is_adjacent_intersection(LineartEdge *e, LineartTriangle *tri)
static bool lineart_triangle_get_other_verts(const LineartTriangle *tri, const LineartVert *vt, LineartVert **l, LineartVert **r)
static void lineart_bounding_area_link_triangle(LineartData *ld, LineartBoundingArea *root_ba, LineartTriangle *tri, double l_r_u_b[4], int recursive, int recursive_level, bool do_intersection, LineartIsecThread *th)
#define LRT_CULL_ENSURE_MEMORY
bool MOD_lineart_compute_feature_lines_v3(Depsgraph *depsgraph, GreasePencilLineartModifierData &lmd, LineartCache **cached_result, bool enable_stroke_depth_offset)
static bool lineart_geometry_check_visible(double model_view_proj[4][4], double shift_x, double shift_y, Mesh *use_mesh)
#define LRT_GUARD_NOT_FOUND
void lineart_register_intersection_shadow_cuts(struct LineartData *ld, struct ListBase *shadow_elns)
#define LRT_BOUND_AREA_CROSSES(b1, b2)
#define LRT_EDGE_BA_MARCHING_BEGIN(fb1, fb2)
#define LRT_EDGE_BA_MARCHING_NEXT(fb1, fb2)
void * lineart_mem_acquire(struct LineartStaticMemPool *smp, size_t size)
void * lineart_list_append_pointer_pool_sized(ListBase *h, struct LineartStaticMemPool *smp, void *data, int size)
void lineart_register_shadow_cuts(struct LineartData *ld, struct LineartEdge *e, struct LineartEdge *shadow_edge)
LineartElementLinkNode * lineart_find_matching_eln(struct ListBase *shadow_elns, int obindex)
#define LRT_EDGE_BA_MARCHING_END
void * lineart_list_append_pointer_pool_thread(ListBase *h, struct LineartStaticMemPool *smp, void *data)
void lineart_main_make_enclosed_shapes(struct LineartData *ld, struct LineartData *shadow_ld)
#define LRT_ITER_ALL_LINES_END
void lineart_count_and_print_render_buffer_memory(struct LineartData *ld)
LineartEdge * lineart_find_matching_edge(struct LineartElementLinkNode *shadow_eln, uint64_t edge_identifier)
void lineart_matrix_perspective_44d(double(*mProjection)[4], double fFov_rad, double fAspect, double zMin, double zMax)
void * lineart_mem_acquire_thread(struct LineartStaticMemPool *smp, size_t size)
void * lineart_list_append_pointer_pool(ListBase *h, struct LineartStaticMemPool *smp, void *data)
void lineart_list_remove_pointer_item_no_free(ListBase *h, LinkData *lip)
#define LRT_ITER_ALL_LINES_BEGIN
void lineart_main_transform_and_add_shadow(struct LineartData *ld, struct LineartElementLinkNode *veln, struct LineartElementLinkNode *eeln)
bool lineart_main_try_generate_shadow_v3(struct Depsgraph *depsgraph, struct Scene *scene, struct LineartData *original_ld, struct GreasePencilLineartModifierData *lmd, struct LineartStaticMemPool *shadow_data_pool, struct LineartElementLinkNode **r_veln, struct LineartElementLinkNode **r_eeln, struct ListBase *r_calculated_edges_eln_list, struct LineartData **r_shadow_ld_if_reproject)
void lineart_mem_destroy(struct LineartStaticMemPool *smp)
void * lineart_list_append_pointer_pool_sized_thread(ListBase *h, LineartStaticMemPool *smp, void *data, int size)
void lineart_matrix_ortho_44d(double(*mProjection)[4], double xMin, double xMax, double yMin, double yMax, double zMin, double zMax)
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 cos(float3 v)
int3 corner_tri_get_real_edges(Span< int2 > edges, Span< int > corner_verts, Span< int > corner_edges, const int3 &corner_tri)
Curves * curves_new_nomain(int points_num, int curves_num)
bke::GeometrySet join_geometries(Span< bke::GeometrySet > geometries, const bke::AttributeFilter &attribute_filter, const std::optional< Span< bke::GeometryComponent::Type > > &component_types_to_join=std::nullopt)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void parallel_sort(RandomAccessIterator begin, RandomAccessIterator end)
Render * RE_GetSceneRender(const Scene *scene)
unsigned __int64 uint64_t
uint8_t lineart_intersection_priority
uint8_t lineart_intersection_mask
blender::Set< const Object * > * included_objects
blender::Span< int > corner_verts
blender::VArray< bool > sharp_edges
LineartEdgeNeighbor * edge_nabr
blender::Span< blender::int2 > edges
blender::Span< int > corner_edges
blender::Span< int > material_indices
blender::VArray< bool > sharp_faces
blender::Span< int3 > corner_tris
LineartTriangle * tri_array
blender::Span< int > tri_faces
LineartAdjacentEdge * adj_e
blender::Span< int > corner_verts
LineartEdgeNeighbor * edge_nabr
blender::Span< int > tri_faces
blender::Span< int3 > corner_tris
float chaining_image_threshold
struct LineartCache * cache
float angle_splitting_threshold
struct LineartData * la_data_ptr
struct Object * source_camera
char shadow_use_silhouette_override
float stroke_depth_offset
short edge_types_override
char shadow_selection_override
struct Object * light_contour_object
float chain_smooth_tolerance
struct LineartBoundingArea * child
struct LineartEdge ** linked_lines
uint32_t insider_triangle_count
struct LineartTriangle ** linked_triangles
uint32_t max_triangle_count
LineartStaticMemPool chain_data_pool
uint16_t all_enabled_edge_types
LineartStaticMemPool shadow_data_pool
float cam_obmat_secondary[4][4]
bool use_contour_secondary
bool filter_face_mark_invert
bool cam_is_persp_secondary
bool use_loose_edge_chain
double view_projection[4][4]
bool shadow_enclose_shapes
bool chain_preserve_details
double view_vector_secondary[3]
double camera_pos_secondary[3]
float chaining_image_threshold
bool filter_face_mark_keep_contour
double active_camera_pos[3]
float chain_smooth_tolerance
bool use_loose_as_contour
bool use_image_boundary_trimming
bool shadow_use_silhouette
bool filter_face_mark_boundaries
bool allow_overlapping_edges
bool allow_duplicated_types
bool use_back_face_culling
float angle_splitting_threshold
bool use_geometry_space_chain
bool light_reference_available
ListBase vertex_buffer_pointers
ListBase line_buffer_pointers
ListBase triangle_adjacent_pointers
ListBase triangle_buffer_pointers
uint32_t initial_tile_count
struct LineartBoundingArea * initials
LineartStaticMemPool render_data_pool
struct LineartData::_conf conf
struct LineartData::_geom geom
struct LineartData::_qtree qtree
int isect_scheduled_up_to_index
LineartElementLinkNode * isect_scheduled_up_to
LineartStaticMemPool * edge_data_pool
struct LineartPendingEdges pending_edges
LineartStaticMemPool * chain_data_pool
struct Object * object_ref
struct LineartEdgeSegment * prev
struct LineartEdgeSegment * next
uint32_t shadow_mask_bits
uint8_t material_mask_bits
struct LineartTriangle * t2
struct LineartTriangle * t1
struct Object * object_ref
eLineArtElementNodeFlag flags
struct LineartElementLinkNode * next
LineartIsecThread * threads
LineartElementLinkNode * pending_from
LineartIsecSingle * array
LineartElementLinkNode * pending_to
std::unique_ptr< blender::Set< const Object * > > object_dependencies
LineartElementLinkNode * v_eln
struct Mesh * original_me
struct LineartPendingEdges pending_edges
double model_view_proj[4][4]
struct Object * original_ob_eval
uint8_t override_intersection_mask
struct LineartObjectInfo * next
uint8_t intersection_priority
struct Object * original_ob
LineartObjectInfo * pending
struct LineartPendingEdges pending_edges
struct LineartEdge * e[3]
struct LineartEdge * testing_e[1]
struct LineartTriangle base
uint8_t material_mask_bits
uint8_t intersection_priority
uint8_t intersection_mask
uint32_t target_reference
struct LinkNode * intersecting_verts
struct LineartVert * v[3]
unsigned char mat_occlusion
unsigned char intersection_priority
unsigned char material_mask_bits
struct MaterialLineArt lineart
MeshRuntimeHandle * runtime
unsigned char intersection_priority
TaskParallelReduceFunc func_reduce
size_t userdata_chunk_size
int lineart_triangle_size
LineartTriangleAdjacent * tri_adj
blender::Span< blender::float3 > positions
blender::Span< int3 > corner_tris
LineartObjectInfo * ob_info
blender::Span< int > corner_verts
blender::Span< int > tri_faces
blender::Span< int > material_indices
LineartTriangle * tri_arr
double(* model_view_proj)[4]
blender::Span< blender::float3 > positions
static GeometrySet from_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Curves * get_curves_for_write()
blender::BitVector is_loose_bits
MutableVArraySpan< T > span
function< void(void)> TaskRunFunction