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) {
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) {
1710 corner_tris[i / 3]);
1712 if (real_edges[i % 3] >= 0) {
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;
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) {
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 |
2076 vert_data.
v_arr = la_v_arr;
2098 tri_data.
tri_arr = la_tri_arr;
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,
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 ||
3131 l->v[2]->index == r->
v[2]->
index ||
l->v[2]->index == r->
v[1]->
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 ||
3138 l->v[2]->index == r->
v[2]->
index ||
l->v[2]->index == r->
v[0]->
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 ||
3145 l->v[2]->index == r->
v[0]->
index ||
l->v[2]->index == r->
v[1]->
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 ||
3152 l->v[0]->index == r->
v[2]->
index ||
l->v[0]->index == r->
v[1]->
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 ||
3159 l->v[0]->index == r->
v[2]->
index ||
l->v[0]->index == r->
v[0]->
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 ||
3166 l->v[0]->index == r->
v[0]->
index ||
l->v[0]->index == r->
v[1]->
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) {
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)) {
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;
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;
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;
5053 use_render_camera_override =
true;
5055 if (!lineart_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) {
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);
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(* TaskRunFunction)(TaskPool *__restrict pool, void *taskdata)
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_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
@ COLLECTION_HIDE_VIEWPORT
@ 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
#define LRT_EDGE_IDENTIFIER(obi, e)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
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
BPy_StructRNA * depsgraph
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
constexpr int64_t size() const
constexpr int64_t last(const int64_t n=0) const
constexpr bool is_empty() const
void append(const T &value)
IndexRange index_range() const
void reserve(const int64_t min_capacity)
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
MutableSpan< float3 > positions_for_write()
MutableAttributeAccessor attributes_for_write()
void fill_curve_types(CurveType type)
MutableSpan< int > offsets_for_write()
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type)
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
void tag_topology_changed()
local_group_size(16, 16) .push_constant(Type b
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)
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)
int3 corner_tri_get_real_edges(Span< int2 > edges, Span< int > corner_verts, Span< int > corner_edges, const int3 &corner_tri)
#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)
MatBase< float, 4, 4 > float4x4
void parallel_sort(RandomAccessIterator begin, RandomAccessIterator end)
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
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
struct Collection * master_collection
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