diff options
Diffstat (limited to 'source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c')
-rw-r--r-- | source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c | 208 |
1 files changed, 121 insertions, 87 deletions
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index 874da3b88c9..c1e71bde254 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -50,7 +50,7 @@ #include "lineart_intern.h" typedef struct LineartIsecSingle { - float v1[3], v2[3]; + double v1[3], v2[3]; LineartTriangle *tri1, *tri2; } LineartIsecSingle; @@ -69,7 +69,7 @@ typedef struct LineartIsecThread { int max; int count_test; - /* For individual thread reference.*/ + /* For individual thread reference. */ LineartData *ld; } LineartIsecThread; @@ -304,13 +304,12 @@ void lineart_edge_cut(LineartData *ld, /* The enclosed shape flag will override regular lit/shaded * flags. See LineartEdgeSegment::shadow_mask_bits for details. */ if (shadow_bits == LRT_SHADOW_MASK_ENCLOSED_SHAPE) { - if (seg->shadow_mask_bits & LRT_SHADOW_MASK_LIT || e->flags & LRT_EDGE_FLAG_LIGHT_CONTOUR) { - seg->shadow_mask_bits &= ~LRT_SHADOW_MASK_LIT; + if (seg->shadow_mask_bits & LRT_SHADOW_MASK_ILLUMINATED || + e->flags & LRT_EDGE_FLAG_LIGHT_CONTOUR) { seg->shadow_mask_bits |= LRT_SHADOW_MASK_INHIBITED; } else if (seg->shadow_mask_bits & LRT_SHADOW_MASK_SHADED) { - seg->shadow_mask_bits &= ~LRT_SHADOW_MASK_SHADED; - seg->shadow_mask_bits |= LRT_SHADOW_MASK_LIT; + seg->shadow_mask_bits |= LRT_SHADOW_MASK_ILLUMINATED_SHAPE; } } else { @@ -1398,7 +1397,7 @@ void lineart_main_discard_out_of_frame_edges(LineartData *ld) LISTBASE_FOREACH (LineartElementLinkNode *, eln, &ld->geom.line_buffer_pointers) { e = (LineartEdge *)eln->pointer; for (i = 0; i < eln->element_count; i++) { - if ((LRT_VERT_OUT_OF_BOUND(e[i].v1) && LRT_VERT_OUT_OF_BOUND(e[i].v2))) { + if (LRT_VERT_OUT_OF_BOUND(e[i].v1) && LRT_VERT_OUT_OF_BOUND(e[i].v2)) { e[i].flags = LRT_EDGE_FLAG_CHAIN_PICKED; } } @@ -1412,7 +1411,7 @@ typedef struct LineartEdgeNeighbor { } LineartEdgeNeighbor; typedef struct VertData { - MVert *mvert; + const MVert *mvert; LineartVert *v_arr; double (*model_view)[4]; double (*model_view_proj)[4]; @@ -1423,7 +1422,7 @@ static void lineart_mvert_transform_task(void *__restrict userdata, const TaskParallelTLS *__restrict UNUSED(tls)) { VertData *vert_task_data = (VertData *)userdata; - MVert *m_v = &vert_task_data->mvert[i]; + const MVert *m_v = &vert_task_data->mvert[i]; double co[4]; LineartVert *v = &vert_task_data->v_arr[i]; copy_v3db_v3fl(co, m_v->co); @@ -1471,8 +1470,9 @@ static LineartTriangle *lineart_triangle_from_index(LineartData *ld, typedef struct EdgeFeatData { LineartData *ld; Mesh *me; - Object *ob; + Object *ob_eval; /* For evaluated materials. */ const MLoopTri *mlooptri; + const int *material_indices; LineartTriangle *tri_array; LineartVert *v_array; float crease_threshold; @@ -1504,7 +1504,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, EdgeFeatData *e_feat_data = (EdgeFeatData *)userdata; EdgeFeatReduceData *reduce_data = (EdgeFeatReduceData *)tls->userdata_chunk; Mesh *me = e_feat_data->me; - Object *ob = e_feat_data->ob; + const int *material_indices = e_feat_data->material_indices; + Object *ob_eval = e_feat_data->ob_eval; LineartEdgeNeighbor *edge_nabr = e_feat_data->edge_nabr; const MLoopTri *mlooptri = e_feat_data->mlooptri; @@ -1637,12 +1638,13 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, } if (!only_contour) { + const MPoly *polys = BKE_mesh_polys(me); if (ld->conf.use_crease) { bool do_crease = true; if (!ld->conf.force_crease && !e_feat_data->use_auto_smooth && - (me->mpoly[mlooptri[f1].poly].flag & ME_SMOOTH) && - (me->mpoly[mlooptri[f2].poly].flag & ME_SMOOTH)) { + (polys[mlooptri[f1].poly].flag & ME_SMOOTH) && + (polys[mlooptri[f2].poly].flag & ME_SMOOTH)) { do_crease = false; } if (do_crease && (dot_v3v3_db(tri1->gn, tri2->gn) < e_feat_data->crease_threshold)) { @@ -1650,12 +1652,12 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, } } - int mat1 = me->mpoly[mlooptri[f1].poly].mat_nr; - int mat2 = me->mpoly[mlooptri[f2].poly].mat_nr; + int mat1 = material_indices ? material_indices[mlooptri[f1].poly] : 0; + int mat2 = material_indices ? material_indices[mlooptri[f2].poly] : 0; if (mat1 != mat2) { - Material *m1 = BKE_object_material_get(ob, mat1 + 1); - Material *m2 = BKE_object_material_get(ob, mat2 + 1); + Material *m1 = BKE_object_material_get_eval(ob_eval, mat1 + 1); + Material *m2 = BKE_object_material_get_eval(ob_eval, mat2 + 1); if (m1 && m2 && ((m1->lineart.mat_occlusion == 0 && m2->lineart.mat_occlusion != 0) || (m2->lineart.mat_occlusion == 0 && m1->lineart.mat_occlusion != 0))) { @@ -1674,11 +1676,13 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, } } + const MEdge *edges = BKE_mesh_edges(me); + int real_edges[3]; BKE_mesh_looptri_get_real_edges(me, &mlooptri[i / 3], real_edges); if (real_edges[i % 3] >= 0) { - MEdge *medge = &me->medge[real_edges[i % 3]]; + const MEdge *medge = &edges[real_edges[i % 3]]; if (ld->conf.use_crease && ld->conf.sharp_as_crease && (medge->flag & ME_SHARP)) { edge_flag_result |= LRT_EDGE_FLAG_CREASE; @@ -1709,16 +1713,16 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, typedef struct LooseEdgeData { int loose_count; int loose_max; - MEdge **loose_array; - Mesh *me; + int *loose_array; + const MEdge *edges; } LooseEdgeData; static void lineart_loose_data_reallocate(LooseEdgeData *loose_data, int count) { - MEdge **new_arr = MEM_callocN(sizeof(MEdge *) * count, "loose edge array"); + int *new_arr = MEM_calloc_arrayN(count, sizeof(int), "loose edge array"); if (loose_data->loose_array) { - memcpy(new_arr, loose_data->loose_array, sizeof(MEdge *) * loose_data->loose_max); - MEM_freeN(loose_data->loose_array); + memcpy(new_arr, loose_data->loose_array, sizeof(int) * loose_data->loose_max); + MEM_SAFE_FREE(loose_data->loose_array); } loose_data->loose_max = count; loose_data->loose_array = new_arr; @@ -1735,19 +1739,19 @@ static void lineart_join_loose_edge_arr(LooseEdgeData *loose_data, LooseEdgeData } memcpy(&loose_data->loose_array[loose_data->loose_count], to_be_joined->loose_array, - sizeof(MEdge *) * to_be_joined->loose_count); + sizeof(int) * to_be_joined->loose_count); loose_data->loose_count += to_be_joined->loose_count; MEM_freeN(to_be_joined->loose_array); to_be_joined->loose_array = NULL; } -static void lineart_add_loose_edge(LooseEdgeData *loose_data, MEdge *e) +static void lineart_add_loose_edge(LooseEdgeData *loose_data, const int i) { if (loose_data->loose_count >= loose_data->loose_max) { int min_amount = MAX2(100, loose_data->loose_count * 2); lineart_loose_data_reallocate(loose_data, min_amount); } - loose_data->loose_array[loose_data->loose_count] = e; + loose_data->loose_array[loose_data->loose_count] = i; loose_data->loose_count++; } @@ -1756,10 +1760,9 @@ static void lineart_identify_loose_edges(void *__restrict UNUSED(userdata), const TaskParallelTLS *__restrict tls) { LooseEdgeData *loose_data = (LooseEdgeData *)tls->userdata_chunk; - Mesh *me = loose_data->me; - if (me->medge[i].flag & ME_LOOSEEDGE) { - lineart_add_loose_edge(loose_data, &me->medge[i]); + if (loose_data->edges[i].flag & ME_LOOSEEDGE) { + lineart_add_loose_edge(loose_data, i); } } @@ -1797,10 +1800,10 @@ static void lineart_add_edge_to_array_thread(LineartObjectInfo *obi, LineartEdge } /* NOTE: For simplicity, this function doesn't actually do anything if you already have data in - * #pe. */ + * #pe. */ void lineart_finalize_object_edge_array_reserve(LineartPendingEdges *pe, int count) { - if (pe->max || pe->array) { + if (pe->max || pe->array || count == 0) { return; } @@ -1842,6 +1845,7 @@ static void lineart_triangle_adjacent_assign(LineartTriangle *tri, typedef struct TriData { LineartObjectInfo *ob_info; const MLoopTri *mlooptri; + const int *material_indices; LineartVert *vert_arr; LineartTriangle *tri_arr; int lineart_triangle_size; @@ -1856,22 +1860,24 @@ static void lineart_load_tri_task(void *__restrict userdata, Mesh *me = tri_task_data->ob_info->original_me; LineartObjectInfo *ob_info = tri_task_data->ob_info; const MLoopTri *mlooptri = &tri_task_data->mlooptri[i]; + const int *material_indices = tri_task_data->material_indices; LineartVert *vert_arr = tri_task_data->vert_arr; LineartTriangle *tri = tri_task_data->tri_arr; + const MLoop *loops = BKE_mesh_loops(me); tri = (LineartTriangle *)(((uchar *)tri) + tri_task_data->lineart_triangle_size * i); - int v1 = me->mloop[mlooptri->tri[0]].v; - int v2 = me->mloop[mlooptri->tri[1]].v; - int v3 = me->mloop[mlooptri->tri[2]].v; + int v1 = loops[mlooptri->tri[0]].v; + int v2 = loops[mlooptri->tri[1]].v; + int v3 = loops[mlooptri->tri[2]].v; tri->v[0] = &vert_arr[v1]; tri->v[1] = &vert_arr[v2]; tri->v[2] = &vert_arr[v3]; /* Material mask bits and occlusion effectiveness assignment. */ - Material *mat = BKE_object_material_get(ob_info->original_ob, - me->mpoly[mlooptri->poly].mat_nr + 1); + Material *mat = BKE_object_material_get( + ob_info->original_ob_eval, material_indices ? material_indices[mlooptri->poly] + 1 : 1); tri->material_mask_bits |= ((mat && (mat->lineart.flags & LRT_MATERIAL_MASK_ENABLED)) ? mat->lineart.material_mask_bits : 0); @@ -1890,7 +1896,8 @@ static void lineart_load_tri_task(void *__restrict userdata, double gn[3]; float no[3]; - normal_tri_v3(no, me->mvert[v1].co, me->mvert[v2].co, me->mvert[v3].co); + const MVert *verts = BKE_mesh_verts(me); + normal_tri_v3(no, verts[v1].co, verts[v2].co, verts[v3].co); copy_v3db_v3fl(gn, no); mul_v3_mat3_m4v3_db(tri->gn, ob_info->normal, gn); normalize_v3_db(tri->gn); @@ -1898,8 +1905,10 @@ static void lineart_load_tri_task(void *__restrict userdata, if (ob_info->usage == OBJECT_LRT_INTERSECTION_ONLY) { tri->flags |= LRT_TRIANGLE_INTERSECTION_ONLY; } - else if (ob_info->usage == OBJECT_LRT_NO_INTERSECTION || - ob_info->usage == OBJECT_LRT_OCCLUSION_ONLY) { + else if (ob_info->usage == OBJECT_LRT_FORCE_INTERSECTION) { + tri->flags |= LRT_TRIANGLE_FORCE_INTERSECTION; + } + else if (ELEM(ob_info->usage, OBJECT_LRT_NO_INTERSECTION, OBJECT_LRT_OCCLUSION_ONLY)) { tri->flags |= LRT_TRIANGLE_NO_INTERSECTION; } @@ -1909,8 +1918,8 @@ static void lineart_load_tri_task(void *__restrict userdata, typedef struct EdgeNeighborData { LineartEdgeNeighbor *edge_nabr; LineartAdjacentEdge *adj_e; - MLoopTri *mlooptri; - MLoop *mloop; + const MLoopTri *mlooptri; + const MLoop *mloop; } EdgeNeighborData; static void lineart_edge_neighbor_init_task(void *__restrict userdata, @@ -1919,9 +1928,9 @@ static void lineart_edge_neighbor_init_task(void *__restrict userdata, { EdgeNeighborData *en_data = (EdgeNeighborData *)userdata; LineartAdjacentEdge *adj_e = &en_data->adj_e[i]; - MLoopTri *looptri = &en_data->mlooptri[i / 3]; + const MLoopTri *looptri = &en_data->mlooptri[i / 3]; LineartEdgeNeighbor *edge_nabr = &en_data->edge_nabr[i]; - MLoop *mloop = en_data->mloop; + const MLoop *mloop = en_data->mloop; adj_e->e = i; adj_e->v1 = mloop[looptri->tri[i % 3]].v; @@ -1944,8 +1953,6 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge LineartEdgeNeighbor *edge_nabr = MEM_mallocN(sizeof(LineartEdgeNeighbor) * total_edges, "LineartEdgeNeighbor arr"); - MLoopTri *mlooptri = me->runtime.looptris.array; - TaskParallelSettings en_settings; BLI_parallel_range_settings_defaults(&en_settings); /* Set the minimum amount of edges a thread has to process. */ @@ -1954,8 +1961,8 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge EdgeNeighborData en_data; en_data.adj_e = adj_e; en_data.edge_nabr = edge_nabr; - en_data.mlooptri = mlooptri; - en_data.mloop = me->mloop; + en_data.mlooptri = BKE_mesh_runtime_looptri_ensure(me); + en_data.mloop = BKE_mesh_loops(me); BLI_task_parallel_range(0, total_edges, &en_data, lineart_edge_neighbor_init_task, &en_settings); @@ -1993,6 +2000,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); const int tot_tri = BKE_mesh_runtime_looptri_len(me); + const int *material_indices = (const int *)CustomData_get_layer_named( + &me->pdata, CD_PROP_INT32, "material_index"); + /* Check if we should look for custom data tags like Freestyle edges or faces. */ bool can_find_freestyle_edge = false; int layer_index = CustomData_get_active_layer_index(&me->edata, CD_FREESTYLE_EDGE); @@ -2078,7 +2088,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, vert_settings.min_iter_per_thread = 4000; VertData vert_data; - vert_data.mvert = me->mvert; + vert_data.mvert = BKE_mesh_verts(me); vert_data.v_arr = la_v_arr; vert_data.model_view = ob_info->model_view; vert_data.model_view_proj = ob_info->model_view_proj; @@ -2096,6 +2106,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, TriData tri_data; tri_data.ob_info = ob_info; tri_data.mlooptri = mlooptri; + tri_data.material_indices = material_indices; tri_data.vert_arr = la_v_arr; tri_data.tri_arr = la_tri_arr; tri_data.lineart_triangle_size = la_data->sizeof_triangle; @@ -2121,8 +2132,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, EdgeFeatData edge_feat_data = {0}; edge_feat_data.ld = la_data; edge_feat_data.me = me; - edge_feat_data.ob = orig_ob; + edge_feat_data.ob_eval = ob_info->original_ob_eval; edge_feat_data.mlooptri = mlooptri; + edge_feat_data.material_indices = material_indices; edge_feat_data.edge_nabr = lineart_build_edge_neighbor(me, total_edges); edge_feat_data.tri_array = la_tri_arr; edge_feat_data.v_array = la_v_arr; @@ -2146,6 +2158,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, &edge_feat_settings); LooseEdgeData loose_data = {0}; + if (la_data->conf.use_loose) { /* Only identifying floating edges at this point because other edges has been taken care of * inside #lineart_identify_mlooptri_feature_edges function. */ @@ -2155,7 +2168,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_loose_settings.func_reduce = loose_data_sum_reduce; edge_loose_settings.userdata_chunk = &loose_data; edge_loose_settings.userdata_chunk_size = sizeof(LooseEdgeData); - loose_data.me = me; + loose_data.edges = BKE_mesh_edges(me); BLI_task_parallel_range( 0, me->totedge, &loose_data, lineart_identify_loose_edges, &edge_loose_settings); } @@ -2238,8 +2251,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, } } - if (usage == OBJECT_LRT_INHERIT || usage == OBJECT_LRT_INCLUDE || - usage == OBJECT_LRT_NO_INTERSECTION) { + if (ELEM(usage, + OBJECT_LRT_INHERIT, + OBJECT_LRT_INCLUDE, + OBJECT_LRT_NO_INTERSECTION, + OBJECT_LRT_FORCE_INTERSECTION)) { lineart_add_edge_to_array_thread(ob_info, la_edge); } @@ -2260,14 +2276,18 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, if (loose_data.loose_array) { for (int i = 0; i < loose_data.loose_count; i++) { - la_edge->v1 = &la_v_arr[loose_data.loose_array[i]->v1]; - la_edge->v2 = &la_v_arr[loose_data.loose_array[i]->v2]; + const MEdge *edge = &loose_data.edges[loose_data.loose_array[i]]; + la_edge->v1 = &la_v_arr[edge->v1]; + la_edge->v2 = &la_v_arr[edge->v2]; la_edge->flags = LRT_EDGE_FLAG_LOOSE; la_edge->object_ref = orig_ob; la_edge->edge_identifier = LRT_EDGE_IDENTIFIER(ob_info, la_edge); BLI_addtail(&la_edge->segments, la_seg); - if (usage == OBJECT_LRT_INHERIT || usage == OBJECT_LRT_INCLUDE || - usage == OBJECT_LRT_NO_INTERSECTION) { + if (ELEM(usage, + OBJECT_LRT_INHERIT, + OBJECT_LRT_INCLUDE, + OBJECT_LRT_NO_INTERSECTION, + OBJECT_LRT_FORCE_INTERSECTION)) { lineart_add_edge_to_array_thread(ob_info, la_edge); if (shadow_eln) { LineartEdge *shadow_e = lineart_find_matching_edge(shadow_eln, la_edge->edge_identifier); @@ -2279,7 +2299,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, la_edge++; la_seg++; } - MEM_freeN(loose_data.loose_array); + MEM_SAFE_FREE(loose_data.loose_array); } MEM_freeN(edge_feat_data.edge_nabr); @@ -2368,6 +2388,8 @@ static int lineart_usage_check(Collection *c, Object *ob, bool is_render) return OBJECT_LRT_INTERSECTION_ONLY; case COLLECTION_LRT_NO_INTERSECTION: return OBJECT_LRT_NO_INTERSECTION; + case COLLECTION_LRT_FORCE_INTERSECTION: + return OBJECT_LRT_FORCE_INTERSECTION; } return OBJECT_LRT_INHERIT; } @@ -2512,6 +2534,7 @@ static void lineart_object_load_single_instance(LineartData *ld, obi->original_me = use_mesh; obi->original_ob = (ref_ob->id.orig_id ? (Object *)ref_ob->id.orig_id : (Object *)ref_ob); + obi->original_ob_eval = DEG_get_evaluated_object(depsgraph, obi->original_ob); lineart_geometry_load_assign_thread(olti, obi, thread_count, use_mesh->totpoly); } @@ -2582,9 +2605,13 @@ void lineart_main_load_geometries(Depsgraph *depsgraph, flags |= DEG_ITER_OBJECT_FLAG_DUPLI; } + DEGObjectIterSettings deg_iter_settings = {0}; + deg_iter_settings.depsgraph = depsgraph; + deg_iter_settings.flags = flags; + /* XXX(@Yiming): Temporary solution, this iterator is technically unsafe to use *during* * depsgraph evaluation, see D14997 for detailed explanations. */ - DEG_OBJECT_ITER_BEGIN (depsgraph, ob, flags) { + DEG_OBJECT_ITER_BEGIN (°_iter_settings, ob) { obindex++; @@ -2651,6 +2678,7 @@ void lineart_main_load_geometries(Depsgraph *depsgraph, } LineartVert *v = (LineartVert *)obi->v_eln->pointer; int v_count = obi->v_eln->element_count; + obi->v_eln->global_index_offset = global_i; for (int vi = 0; vi < v_count; vi++) { v[vi].index += global_i; } @@ -2861,7 +2889,7 @@ static bool lineart_triangle_edge_image_space_occlusion(const LineartTriangle *t if ((e->flags & LRT_EDGE_FLAG_PROJECTED_SHADOW) && (e->target_reference == tri->target_reference)) { if (((dot_f > 0) && (e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT)) || - ((dot_f < 0) && (!(e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT)))) { + ((dot_f < 0) && !(e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT))) { *from = 0.0f; *to = 1.0f; return true; @@ -3187,8 +3215,7 @@ static bool lineart_triangle_2v_intersection_math( return false; } - if (!(lineart_point_inside_triangle3d( - gloc, tri->v[0]->gloc, tri->v[1]->gloc, tri->v[2]->gloc))) { + if (!lineart_point_inside_triangle3d(gloc, tri->v[0]->gloc, tri->v[1]->gloc, tri->v[2]->gloc)) { return false; } @@ -3286,8 +3313,8 @@ static void lineart_add_isec_thread(LineartIsecThread *th, th->array = new_array; } LineartIsecSingle *isec_single = &th->array[th->current]; - copy_v3fl_v3db(isec_single->v1, v1); - copy_v3fl_v3db(isec_single->v2, v2); + copy_v3_v3_db(isec_single->v1, v1); + copy_v3_v3_db(isec_single->v2, v2); isec_single->tri1 = tri1; isec_single->tri2 = tri2; if (tri1->target_reference > tri2->target_reference) { @@ -3394,10 +3421,11 @@ static void lineart_triangle_intersect_in_bounding_area(LineartTriangle *tri, } tt->testing_e[th->thread_id] = (LineartEdge *)tri; - if ((testing_triangle->flags & LRT_TRIANGLE_NO_INTERSECTION) || - ((testing_triangle->flags & LRT_TRIANGLE_INTERSECTION_ONLY) && - (tri->flags & LRT_TRIANGLE_INTERSECTION_ONLY))) { - continue; + if (!((testing_triangle->flags | tri->flags) & LRT_TRIANGLE_FORCE_INTERSECTION)) { + if (((testing_triangle->flags | tri->flags) & LRT_TRIANGLE_NO_INTERSECTION) || + (testing_triangle->flags & tri->flags & LRT_TRIANGLE_INTERSECTION_ONLY)) { + continue; + } } double *RG0 = testing_triangle->v[0]->gloc, *RG1 = testing_triangle->v[1]->gloc, @@ -3643,7 +3671,8 @@ static LineartData *lineart_create_render_buffer(Scene *scene, (lmd->light_contour_object != NULL)); ld->conf.shadow_selection = lmd->shadow_selection_override; - ld->conf.shadow_enclose_shapes = (lmd->calculation_flags & LRT_SHADOW_ENCLOSED_SHAPES) != 0; + ld->conf.shadow_enclose_shapes = lmd->shadow_selection_override == + LRT_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES; ld->conf.shadow_use_silhouette = lmd->shadow_use_silhouette_override != 0; ld->conf.use_back_face_culling = (lmd->calculation_flags & LRT_USE_BACK_FACE_CULLING) != 0; @@ -4091,7 +4120,6 @@ static bool lineart_bounding_area_triangle_intersect(LineartData *fb, * (#LineartBoundingArea) for intersection lines. When splitting the tile into 4 children and * re-linking triangles into the child tiles, intersections are inhibited so we don't get * duplicated intersection lines. - * */ static void lineart_bounding_area_link_triangle(LineartData *ld, LineartBoundingArea *root_ba, @@ -4519,14 +4547,8 @@ static void lineart_add_triangles_worker(TaskPool *__restrict UNUSED(pool), Line _dir_control++; for (co = x1; co <= x2; co++) { for (r = y1; r <= y2; r++) { - lineart_bounding_area_link_triangle(ld, - &ld->qtree.initials[r * ld->qtree.count_x + co], - tri, - 0, - 1, - 0, - (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)), - th); + lineart_bounding_area_link_triangle( + ld, &ld->qtree.initials[r * ld->qtree.count_x + co], tri, 0, 1, 0, 1, th); } } } /* Else throw away. */ @@ -4582,8 +4604,8 @@ static void lineart_create_edges_from_isec_data(LineartIsecData *d) LineartIsecSingle *is = &th->array[j]; LineartVert *v1 = v; LineartVert *v2 = v + 1; - copy_v3db_v3fl(v1->gloc, is->v1); - copy_v3db_v3fl(v2->gloc, is->v2); + copy_v3_v3_db(v1->gloc, is->v1); + copy_v3_v3_db(v2->gloc, is->v2); /* The intersection line has been generated only in geometry space, so we need to transform * them as well. */ mul_v4_m4v3_db(v1->fbcoord, ld->conf.view_projection, v1->gloc); @@ -4655,7 +4677,7 @@ void lineart_main_add_triangles(LineartData *ld) } /* Initialize per-thread data for thread task scheduling information and storing intersection - * results. */ + * results. */ LineartIsecData d = {0}; lineart_init_isec_thread(&d, ld, ld->thread_count); @@ -5105,6 +5127,8 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, /* At last, we need to clear flags so we don't confuse GPencil generation calls. */ MOD_lineart_chain_clear_picked_flag(lc); + + MOD_lineart_finalize_chains(ld); } lineart_mem_destroy(&lc->shadow_data_pool); @@ -5228,12 +5252,21 @@ static void lineart_gpencil_generate(LineartCache *cache, if (shaodow_selection) { if (ec->shadow_mask_bits != LRT_SHADOW_MASK_UNDEFINED) { /* TODO(@Yiming): Give a behavior option for how to display undefined shadow info. */ - if ((shaodow_selection == LRT_SHADOW_FILTER_LIT && - (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_LIT))) || - (shaodow_selection == LRT_SHADOW_FILTER_SHADED && - (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_SHADED)))) { + if (shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED && + !(ec->shadow_mask_bits & LRT_SHADOW_MASK_ILLUMINATED)) { continue; } + if (shaodow_selection == LRT_SHADOW_FILTER_SHADED && + !(ec->shadow_mask_bits & LRT_SHADOW_MASK_SHADED)) { + continue; + } + if (shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES) { + uint32_t test_bits = ec->shadow_mask_bits & LRT_SHADOW_TEST_SHAPE_BITS; + if ((test_bits != LRT_SHADOW_MASK_ILLUMINATED) && + (test_bits != (LRT_SHADOW_MASK_SHADED | LRT_SHADOW_MASK_ILLUMINATED_SHAPE))) { + continue; + } + } } } if (silhouette_mode && (ec->type & (LRT_EDGE_FLAG_CONTOUR))) { @@ -5290,11 +5323,12 @@ static void lineart_gpencil_generate(LineartCache *cache, if (source_vgname && vgname) { Object *eval_ob = DEG_get_evaluated_object(depsgraph, ec->object_ref); int gpdg = -1; - if ((match_output || (gpdg = BKE_object_defgroup_name_index(gpencil_object, vgname)) >= 0)) { + if (match_output || (gpdg = BKE_object_defgroup_name_index(gpencil_object, vgname)) >= 0) { if (eval_ob && eval_ob->type == OB_MESH) { int dindex = 0; Mesh *me = BKE_object_get_evaluated_mesh(eval_ob); - if (me->dvert) { + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me); + if (dvert) { LISTBASE_FOREACH (bDeformGroup *, db, &me->vertex_group_names) { if ((!source_vgname) || strstr(db->name, source_vgname) == db->name) { if (match_output) { @@ -5309,7 +5343,7 @@ static void lineart_gpencil_generate(LineartCache *cache, if (vindex >= me->totvert) { break; } - MDeformWeight *mdw = BKE_defvert_ensure_index(&me->dvert[vindex], dindex); + MDeformWeight *mdw = BKE_defvert_ensure_index(&dvert[vindex], dindex); MDeformWeight *gdw = BKE_defvert_ensure_index(&gps->dvert[sindex], gpdg); float use_weight = mdw->weight; |