LineArt: Fix (unreported) wrong index in weight transfer

Line art now uses global index for vertices but needs to have
local index in order to do correct weight transfer.
This commit is contained in:
YimingWu 2022-08-18 20:46:04 +08:00
parent d9c48d94e4
commit 66fecfcda6
4 changed files with 42 additions and 0 deletions

View File

@ -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;
@ -864,6 +869,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.

View File

@ -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) {

View File

@ -2651,6 +2651,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;
}
@ -5106,6 +5107,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);

View File

@ -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,