diff options
Diffstat (limited to 'source/blender/gpencil_modifiers')
7 files changed, 146 insertions, 74 deletions
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt index 947fc32f8c0..5ef9ae1bbc6 100644 --- a/source/blender/gpencil_modifiers/CMakeLists.txt +++ b/source/blender/gpencil_modifiers/CMakeLists.txt @@ -94,8 +94,6 @@ endif() set(LIB ) -add_definitions(${GL_DEFINITIONS}) - blender_add_lib(bf_gpencil_modifiers "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") add_dependencies(bf_gpencil_modifiers bf_dna) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index 6bb59f29b98..018a13a1c48 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -397,7 +397,12 @@ static void edge_types_panel_draw(const bContext *UNUSED(C), Panel *panel) sub = uiLayoutRow(entry, false); uiItemR(sub, ptr, "use_light_contour", 0, IFACE_("Light Contour"), ICON_NONE); - uiItemR(entry, ptr, "use_shadow", 0, IFACE_("Cast Shadow"), ICON_NONE); + uiItemR(entry, + ptr, + "use_shadow", + 0, + CTX_IFACE_(BLT_I18NCONTEXT_ID_GPENCIL, "Cast Shadow"), + ICON_NONE); uiItemL(layout, IFACE_("Options"), ICON_NONE); @@ -442,8 +447,8 @@ static void options_light_reference_draw(const bContext *UNUSED(C), Panel *panel uiItemR(remaining, ptr, "shadow_camera_size", 0, NULL, ICON_NONE); uiLayout *col = uiLayoutColumn(remaining, true); - uiItemR(col, ptr, "shadow_camera_near", 0, "Near", ICON_NONE); - uiItemR(col, ptr, "shadow_camera_far", 0, "Far", ICON_NONE); + uiItemR(col, ptr, "shadow_camera_near", 0, IFACE_("Near"), ICON_NONE); + uiItemR(col, ptr, "shadow_camera_far", 0, IFACE_("Far"), ICON_NONE); } static void options_panel_draw(const bContext *UNUSED(C), Panel *panel) diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 63433113822..22037d10a71 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -84,6 +84,7 @@ typedef struct LineartElementLinkNode { /* For edge element link nodes, used for shadow edge matching. */ int obindex; + int global_index_offset; /** Per object value, always set, if not enabled by #ObjectLineArt, then it's set to global. */ float crease_threshold; @@ -205,6 +206,10 @@ typedef struct LineartEdgeChain { uint8_t intersection_mask; uint32_t shadow_mask_bits; + /* We need local index for correct weight transfer, line art index is global, thus + * local_index=lineart_index-index_offset. */ + uint32_t index_offset; + struct Object *object_ref; struct Object *silhouette_backdrop; } LineartEdgeChain; @@ -437,6 +442,7 @@ typedef enum eLineartTriangleFlags { LRT_TRIANGLE_INTERSECTION_ONLY = (1 << 3), LRT_TRIANGLE_NO_INTERSECTION = (1 << 4), LRT_TRIANGLE_MAT_BACK_FACE_CULLING = (1 << 5), + LRT_TRIANGLE_FORCE_INTERSECTION = (1 << 6), } eLineartTriangleFlags; #define LRT_SHADOW_MASK_UNDEFINED 0 @@ -483,6 +489,7 @@ typedef struct LineartRenderTaskInfo { typedef struct LineartObjectInfo { struct LineartObjectInfo *next; struct Object *original_ob; + struct Object *original_ob_eval; /* For evaluated materials */ struct Mesh *original_me; double model_view_proj[4][4]; double model_view[4][4]; @@ -864,6 +871,7 @@ void MOD_lineart_chain_find_silhouette_backdrop_objects(LineartData *ld); int MOD_lineart_chain_count(const LineartEdgeChain *ec); void MOD_lineart_chain_clear_picked_flag(LineartCache *lc); +void MOD_lineart_finalize_chains(LineartData *ld); /** * This is the entry point of all line art calculations. diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c index 7c8e0c5a6f5..f32141a31eb 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c @@ -1051,6 +1051,38 @@ void MOD_lineart_chain_clear_picked_flag(LineartCache *lc) } } +LineartElementLinkNode *lineart_find_matching_eln_obj(ListBase *elns, struct Object *obj) +{ + LISTBASE_FOREACH (LineartElementLinkNode *, eln, elns) { + if (eln->object_ref == obj) { + return eln; + } + } + return NULL; +} + +void MOD_lineart_finalize_chains(LineartData *ld) +{ + LISTBASE_FOREACH (LineartEdgeChain *, ec, &ld->chains) { + if (ELEM(ec->type, + LRT_EDGE_FLAG_INTERSECTION, + LRT_EDGE_FLAG_PROJECTED_SHADOW, + LRT_EDGE_FLAG_LIGHT_CONTOUR)) { + continue; + } + LineartElementLinkNode *eln = lineart_find_matching_eln_obj(&ld->geom.vertex_buffer_pointers, + ec->object_ref); + BLI_assert(eln != NULL); + if (LIKELY(eln)) { + LISTBASE_FOREACH (LineartEdgeChainItem *, eci, &ec->chain) { + if (eci->index > eln->global_index_offset) { + eci->index -= eln->global_index_offset; + } + } + } + } +} + void MOD_lineart_smooth_chains(LineartData *ld, float tolerance) { LISTBASE_FOREACH (LineartEdgeChain *, ec, &ld->chains) { diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index 0fd1d8ff51d..c12521b7347 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -69,7 +69,7 @@ typedef struct LineartIsecThread { int max; int count_test; - /* For individual thread reference.*/ + /* For individual thread reference. */ LineartData *ld; } LineartIsecThread; @@ -1411,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]; @@ -1422,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); @@ -1470,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; @@ -1503,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; @@ -1636,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)) { @@ -1649,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))) { @@ -1673,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; @@ -1708,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; @@ -1734,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++; } @@ -1755,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); } } @@ -1796,7 +1800,7 @@ 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 || count == 0) { @@ -1841,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; @@ -1855,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); @@ -1889,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); @@ -1897,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; } @@ -1908,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, @@ -1918,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; @@ -1954,7 +1964,7 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge en_data.adj_e = adj_e; en_data.edge_nabr = edge_nabr; en_data.mlooptri = mlooptri; - en_data.mloop = me->mloop; + en_data.mloop = BKE_mesh_loops(me); BLI_task_parallel_range(0, total_edges, &en_data, lineart_edge_neighbor_init_task, &en_settings); @@ -1992,6 +2002,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); @@ -2077,7 +2090,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; @@ -2095,6 +2108,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; @@ -2120,8 +2134,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; @@ -2145,6 +2160,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. */ @@ -2154,7 +2170,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); } @@ -2237,8 +2253,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); } @@ -2259,14 +2278,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); @@ -2278,7 +2301,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); @@ -2367,6 +2390,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; } @@ -2511,6 +2536,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); } @@ -2581,9 +2607,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++; @@ -2650,6 +2680,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; } @@ -3393,10 +3424,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 & 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, @@ -4091,7 +4123,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 +4550,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. */ @@ -4655,7 +4680,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 +5130,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); @@ -5227,16 +5254,16 @@ 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. */ + /* TODO(@Yiming): Give a behavior option for how to display undefined shadow info. */ if ((shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED && (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_ILLUMINATED)))) { continue; } - else if ((shaodow_selection == LRT_SHADOW_FILTER_SHADED && - (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_SHADED)))) { + if ((shaodow_selection == LRT_SHADOW_FILTER_SHADED && + (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_SHADED)))) { continue; } - else if (shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES) { + 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))) { @@ -5303,7 +5330,8 @@ static void lineart_gpencil_generate(LineartCache *cache, 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) { @@ -5318,7 +5346,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; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h index 3668f1dc6d7..947586aaec4 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h @@ -133,6 +133,7 @@ void lineart_main_transform_and_add_shadow(struct LineartData *ld, struct LineartElementLinkNode *eeln); LineartElementLinkNode *lineart_find_matching_eln(struct ListBase *shadow_elns, int obindex); +LineartElementLinkNode *lineart_find_matching_eln_obj(struct ListBase *elns, struct Object *ob); LineartEdge *lineart_find_matching_edge(struct LineartElementLinkNode *shadow_eln, uint64_t edge_identifier); void lineart_register_shadow_cuts(struct LineartData *ld, diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c index bf42677d79c..257184bae1e 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c @@ -1303,7 +1303,7 @@ static void lineart_shadow_finalize_shadow_edges_task( int v2i = (e[i].edge_identifier & LRT_OBINDEX_LOWER); LineartVert *v = (LineartVert *)eln->pointer; /* If the global position is close enough, use the original vertex to prevent flickering - * caused by very slim boundary condition in point_triangle_relation().*/ + * caused by very slim boundary condition in point_triangle_relation(). */ if (LRT_CLOSE_LOOSER_v3(e[i].v1->gloc, v[v1i].gloc)) { e[i].v1 = &v[v1i]; } |