Fix #118425: LineArt: ensure long edges are shown

Line art used to not calculate edges where both ends are outside image
frame, this will lead to missing edges in some cases where the model is
scaled up pretty big. Now it ensures those edges are still preserved.

Pull Request: https://projects.blender.org/blender/blender/pulls/118448
This commit is contained in:
YimingWu 2024-02-26 04:50:48 +01:00 committed by YimingWu
parent 0a339231ec
commit e938b516a9

@ -16,6 +16,7 @@
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.hh"
#include "BLI_sort.hh"
#include "BLI_task.h"
#include "BLI_time.h"
@ -1392,16 +1393,29 @@ void lineart_main_perspective_division(LineartData *ld)
void lineart_main_discard_out_of_frame_edges(LineartData *ld)
{
LineartEdge *e;
int i;
const float bounds[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, -1.0f}, {1.0f, 1.0f}};
#define LRT_VERT_OUT_OF_BOUND(v) \
(v && (v->fbcoord[0] < -1 || v->fbcoord[0] > 1 || v->fbcoord[1] < -1 || v->fbcoord[1] > 1))
(v->fbcoord[0] < -1 || v->fbcoord[0] > 1 || v->fbcoord[1] < -1 || v->fbcoord[1] > 1)
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)) {
for (int i = 0; i < eln->element_count; i++) {
if (!e[i].v1 || !e[i].v2) {
e[i].flags = LRT_EDGE_FLAG_CHAIN_PICKED;
continue;
}
const blender::float2 vec1(e[i].v1->fbcoord), vec2(e[i].v2->fbcoord);
if (LRT_VERT_OUT_OF_BOUND(e[i].v1) && LRT_VERT_OUT_OF_BOUND(e[i].v2)) {
/* A line could still cross the image border even when both of the vertices are out of
* bound. */
if (isect_seg_seg_v2(bounds[0], bounds[1], vec1, vec2) == ISECT_LINE_LINE_NONE &&
isect_seg_seg_v2(bounds[0], bounds[2], vec1, vec2) == ISECT_LINE_LINE_NONE &&
isect_seg_seg_v2(bounds[1], bounds[3], vec1, vec2) == ISECT_LINE_LINE_NONE &&
isect_seg_seg_v2(bounds[2], bounds[3], vec1, vec2) == ISECT_LINE_LINE_NONE)
{
e[i].flags = LRT_EDGE_FLAG_CHAIN_PICKED;
}
}
}
}