GPencil: Speed up Occlude Eraser

This is an initial change to speed up the calculation of the Occlude eraser. In the future, we can add more optimizations, but at least this increase speed.

Intead to check always the 3 points, the check is skipped if it's not required.

Base in a solution by Philipp Oeser.

This is related to T88412
This commit is contained in:
Antonio Vazquez 2021-05-21 16:54:58 +02:00 committed by Philipp Oeser
parent 1d8d6c2f62
commit 4796865b46
Notes: blender-bot 2023-02-14 00:57:33 +01:00
Referenced by issue #88449: Blender LTS: Maintenance Task 2.93
Referenced by issue #88449, Blender LTS: Maintenance Task 2.93
2 changed files with 28 additions and 4 deletions

View File

@ -1332,7 +1332,7 @@ static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
/* only erase stroke points that are visible */
static bool gpencil_stroke_eraser_is_occluded(
tGPsdata *p, bGPDlayer *gpl, const bGPDspoint *pt, const int x, const int y)
tGPsdata *p, bGPDlayer *gpl, bGPDspoint *pt, const int x, const int y)
{
Object *obact = (Object *)p->ownerPtr.data;
Brush *brush = p->brush;
@ -1364,7 +1364,11 @@ static bool gpencil_stroke_eraser_is_occluded(
mul_v3_m4v3(fpt, diff_mat, &pt->x);
const float depth_pt = view3d_point_depth(rv3d, fpt);
/* Checked occlusion flag. */
pt->flag |= GP_SPOINT_TEMP_TAG;
if (depth_pt > depth_mval) {
/* Is occluded. */
pt->flag |= GP_SPOINT_TEMP_TAG2;
return true;
}
}
@ -1540,6 +1544,10 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
for (i = 0; i < gps->totpoints; i++) {
bGPDspoint *pt = &gps->points[i];
pt->flag &= ~GP_SPOINT_TAG;
/* Occlusion already checked. */
pt->flag &= ~GP_SPOINT_TEMP_TAG;
/* Point is occluded. */
pt->flag &= ~GP_SPOINT_TEMP_TAG2;
}
/* First Pass: Loop over the points in the stroke
@ -1585,9 +1593,23 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
* - this assumes that linewidth is irrelevant
*/
if (gpencil_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
if ((gpencil_stroke_eraser_is_occluded(p, gpl, pt0, pc0[0], pc0[1]) == false) ||
(gpencil_stroke_eraser_is_occluded(p, gpl, pt1, pc1[0], pc1[1]) == false) ||
(gpencil_stroke_eraser_is_occluded(p, gpl, pt2, pc2[0], pc2[1]) == false)) {
bool is_occluded_pt0, is_occluded_pt1, is_occluded_pt2 = true;
is_occluded_pt0 = (pt0 && ((pt0->flag & GP_SPOINT_TEMP_TAG) != 0)) ?
((pt0->flag & GP_SPOINT_TEMP_TAG2) != 0) :
gpencil_stroke_eraser_is_occluded(p, gpl, pt0, pc0[0], pc0[1]);
if (is_occluded_pt0) {
is_occluded_pt1 = ((pt1->flag & GP_SPOINT_TEMP_TAG) != 0) ?
((pt1->flag & GP_SPOINT_TEMP_TAG2) != 0) :
gpencil_stroke_eraser_is_occluded(p, gpl, pt1, pc1[0], pc1[1]);
if (is_occluded_pt1) {
is_occluded_pt2 = ((pt2->flag & GP_SPOINT_TEMP_TAG) != 0) ?
((pt2->flag & GP_SPOINT_TEMP_TAG2) != 0) :
gpencil_stroke_eraser_is_occluded(p, gpl, pt2, pc2[0], pc2[1]);
}
}
if (!is_occluded_pt0 || !is_occluded_pt1 || !is_occluded_pt2) {
/* Point is affected: */
/* Adjust thickness
* - Influence of eraser falls off with distance from the middle of the eraser

View File

@ -112,6 +112,8 @@ typedef enum eGPDspoint_Flag {
GP_SPOINT_TAG = (1 << 1),
/* stroke point is temp tagged (for some editing operation) */
GP_SPOINT_TEMP_TAG = (1 << 2),
/* stroke point is temp tagged (for some editing operation) */
GP_SPOINT_TEMP_TAG2 = (1 << 3),
} eGPSPoint_Flag;
/* ***************************************** */