Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/gpencil/annotate_paint.c
| Show First 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | typedef struct tGPsdata { | ||||
| char *align_flag; /* projection-mode flags (toolsettings - eGPencil_Placement_Flags) */ | char *align_flag; /* projection-mode flags (toolsettings - eGPencil_Placement_Flags) */ | ||||
| eGPencil_PaintStatus status; /* current status of painting */ | eGPencil_PaintStatus status; /* current status of painting */ | ||||
| eGPencil_PaintModes paintmode; /* mode for painting */ | eGPencil_PaintModes paintmode; /* mode for painting */ | ||||
| eGPencil_PaintFlags flags; /* flags that can get set during runtime (eGPencil_PaintFlags) */ | eGPencil_PaintFlags flags; /* flags that can get set during runtime (eGPencil_PaintFlags) */ | ||||
| short radius; /* radius of influence for eraser */ | short radius; /* radius of influence for eraser */ | ||||
| int mval[2]; /* current mouse-position */ | float mval[2]; /* current mouse-position */ | ||||
| int mvalo[2]; /* previous recorded mouse-position */ | float mvalo[2]; /* previous recorded mouse-position */ | ||||
| float pressure; /* current stylus pressure */ | float pressure; /* current stylus pressure */ | ||||
| float opressure; /* previous stylus pressure */ | float opressure; /* previous stylus pressure */ | ||||
| /* These need to be doubles, as (at least under unix) they are in seconds since epoch, | /* These need to be doubles, as (at least under unix) they are in seconds since epoch, | ||||
| * float (and its 7 digits precision) is definitively not enough here! | * float (and its 7 digits precision) is definitively not enough here! | ||||
| * double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least. | * double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least. | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | static void gp_get_3d_reference(tGPsdata *p, float vec[3]) | ||||
| /* use 3D-cursor */ | /* use 3D-cursor */ | ||||
| copy_v3_v3(vec, fp); | copy_v3_v3(vec, fp); | ||||
| } | } | ||||
| /* Stroke Editing ---------------------------- */ | /* Stroke Editing ---------------------------- */ | ||||
| /* check if the current mouse position is suitable for adding a new point */ | /* check if the current mouse position is suitable for adding a new point */ | ||||
| static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2]) | static bool gp_stroke_filtermval(tGPsdata *p, const float mval[2], float pmval[2]) | ||||
| { | { | ||||
| int dx = abs(mval[0] - pmval[0]); | int dx = (int)fabsf(mval[0] - pmval[0]); | ||||
| int dy = abs(mval[1] - pmval[1]); | int dy = (int)fabsf(mval[1] - pmval[1]); | ||||
| /* if buffer is empty, just let this go through (i.e. so that dots will work) */ | /* if buffer is empty, just let this go through (i.e. so that dots will work) */ | ||||
| if (p->gpd->runtime.sbuffer_size == 0) | if (p->gpd->runtime.sbuffer_size == 0) | ||||
| return true; | return true; | ||||
| /* check if mouse moved at least certain distance on both axes (best case) | /* check if mouse moved at least certain distance on both axes (best case) | ||||
| * - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand | * - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand | ||||
| */ | */ | ||||
| else if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) | else if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) | ||||
| return true; | return true; | ||||
| /* check if the distance since the last point is significant enough | /* check if the distance since the last point is significant enough | ||||
| * - prevents points being added too densely | * - prevents points being added too densely | ||||
| * - distance here doesn't use sqrt to prevent slowness... we should still be safe from overflows though | * - distance here doesn't use sqrt to prevent slowness... we should still be safe from overflows though | ||||
| */ | */ | ||||
| else if ((dx * dx + dy * dy) > MIN_EUCLIDEAN_PX * MIN_EUCLIDEAN_PX) | else if ((dx * dx + dy * dy) > MIN_EUCLIDEAN_PX * MIN_EUCLIDEAN_PX) | ||||
| return true; | return true; | ||||
| /* mouse 'didn't move' */ | /* mouse 'didn't move' */ | ||||
| else | else | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* convert screen-coordinates to buffer-coordinates */ | /* convert screen-coordinates to buffer-coordinates */ | ||||
| static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3], float *depth) | static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[3], float *depth) | ||||
| { | { | ||||
| bGPdata *gpd = p->gpd; | bGPdata *gpd = p->gpd; | ||||
| /* in 3d-space - pt->x/y/z are 3 side-by-side floats */ | /* in 3d-space - pt->x/y/z are 3 side-by-side floats */ | ||||
| if (gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) { | if (gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) { | ||||
| if (gpencil_project_check(p) && (ED_view3d_autodist_simple(p->ar, mval, out, 0, depth))) { | int mval_i[2]; | ||||
| round_v2i_v2fl(mval_i, mval); | |||||
| if (gpencil_project_check(p) && (ED_view3d_autodist_simple(p->ar, mval_i, out, 0, depth))) { | |||||
| /* projecting onto 3D-Geometry | /* projecting onto 3D-Geometry | ||||
| * - nothing more needs to be done here, since view_autodist_simple() has already done it | * - nothing more needs to be done here, since view_autodist_simple() has already done it | ||||
| */ | */ | ||||
| } | } | ||||
| else { | else { | ||||
| float mval_prj[2]; | float mval_prj[2]; | ||||
| float rvec[3], dvec[3]; | float rvec[3], dvec[3]; | ||||
| float mval_f[2] = {UNPACK2(mval)}; | |||||
| float zfac; | float zfac; | ||||
| /* Current method just converts each point in screen-coordinates to | /* Current method just converts each point in screen-coordinates to | ||||
| * 3D-coordinates using the 3D-cursor as reference. In general, this | * 3D-coordinates using the 3D-cursor as reference. In general, this | ||||
| * works OK, but it could of course be improved. | * works OK, but it could of course be improved. | ||||
| * | * | ||||
| * TODO: | * TODO: | ||||
| * - investigate using nearest point(s) on a previous stroke as | * - investigate using nearest point(s) on a previous stroke as | ||||
| * reference point instead or as offset, for easier stroke matching | * reference point instead or as offset, for easier stroke matching | ||||
| */ | */ | ||||
| gp_get_3d_reference(p, rvec); | gp_get_3d_reference(p, rvec); | ||||
| zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL); | zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL); | ||||
| if (ED_view3d_project_float_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { | if (ED_view3d_project_float_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { | ||||
| sub_v2_v2v2(mval_f, mval_prj, mval_f); | float mval_f[2]; | ||||
| sub_v2_v2v2(mval_f, mval_prj, mval); | |||||
| ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac); | ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac); | ||||
| sub_v3_v3v3(out, rvec, dvec); | sub_v3_v3v3(out, rvec, dvec); | ||||
| } | } | ||||
| else { | else { | ||||
| zero_v3(out); | zero_v3(out); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Show All 14 Lines | else { /* camera view, use subrect */ | ||||
| out[0] = ((mval[0] - p->subrect->xmin) / BLI_rctf_size_x(p->subrect)) * 100; | out[0] = ((mval[0] - p->subrect->xmin) / BLI_rctf_size_x(p->subrect)) * 100; | ||||
| out[1] = ((mval[1] - p->subrect->ymin) / BLI_rctf_size_y(p->subrect)) * 100; | out[1] = ((mval[1] - p->subrect->ymin) / BLI_rctf_size_y(p->subrect)) * 100; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* add current stroke-point to buffer (returns whether point was successfully added) */ | /* add current stroke-point to buffer (returns whether point was successfully added) */ | ||||
| static short gp_stroke_addpoint( | static short gp_stroke_addpoint( | ||||
| tGPsdata *p, const int mval[2], float pressure, double curtime) | tGPsdata *p, const float mval[2], float pressure, double curtime) | ||||
| { | { | ||||
| bGPdata *gpd = p->gpd; | bGPdata *gpd = p->gpd; | ||||
| tGPspoint *pt; | tGPspoint *pt; | ||||
| ToolSettings *ts = p->scene->toolsettings; | ToolSettings *ts = p->scene->toolsettings; | ||||
| /* check painting mode */ | /* check painting mode */ | ||||
| if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { | if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { | ||||
| /* straight lines only - i.e. only store start and end point in buffer */ | /* straight lines only - i.e. only store start and end point in buffer */ | ||||
| if (gpd->runtime.sbuffer_size == 0) { | if (gpd->runtime.sbuffer_size == 0) { | ||||
| /* first point in buffer (start point) */ | /* first point in buffer (start point) */ | ||||
| pt = (tGPspoint *)(gpd->runtime.sbuffer); | pt = (tGPspoint *)(gpd->runtime.sbuffer); | ||||
| /* store settings */ | /* store settings */ | ||||
| copy_v2_v2_int(&pt->x, mval); | copy_v2_v2(&pt->x, mval); | ||||
| pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ | pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ | ||||
| pt->strength = 1.0f; | pt->strength = 1.0f; | ||||
| pt->time = (float)(curtime - p->inittime); | pt->time = (float)(curtime - p->inittime); | ||||
| /* increment buffer size */ | /* increment buffer size */ | ||||
| gpd->runtime.sbuffer_size++; | gpd->runtime.sbuffer_size++; | ||||
| } | } | ||||
| else { | else { | ||||
| /* just reset the endpoint to the latest value | /* just reset the endpoint to the latest value | ||||
| * - assume that pointers for this are always valid... | * - assume that pointers for this are always valid... | ||||
| */ | */ | ||||
| pt = ((tGPspoint *)(gpd->runtime.sbuffer) + 1); | pt = ((tGPspoint *)(gpd->runtime.sbuffer) + 1); | ||||
| /* store settings */ | /* store settings */ | ||||
| copy_v2_v2_int(&pt->x, mval); | copy_v2_v2(&pt->x, mval); | ||||
| pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ | pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ | ||||
| pt->strength = 1.0f; | pt->strength = 1.0f; | ||||
| pt->time = (float)(curtime - p->inittime); | pt->time = (float)(curtime - p->inittime); | ||||
| /* now the buffer has 2 points (and shouldn't be allowed to get any larger) */ | /* now the buffer has 2 points (and shouldn't be allowed to get any larger) */ | ||||
| gpd->runtime.sbuffer_size = 2; | gpd->runtime.sbuffer_size = 2; | ||||
| } | } | ||||
| /* can keep carrying on this way :) */ | /* can keep carrying on this way :) */ | ||||
| return GP_STROKEADD_NORMAL; | return GP_STROKEADD_NORMAL; | ||||
| } | } | ||||
| else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */ | else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */ | ||||
| /* check if still room in buffer */ | /* check if still room in buffer */ | ||||
| if (gpd->runtime.sbuffer_size >= GP_STROKE_BUFFER_MAX) | if (gpd->runtime.sbuffer_size >= GP_STROKE_BUFFER_MAX) | ||||
| return GP_STROKEADD_OVERFLOW; | return GP_STROKEADD_OVERFLOW; | ||||
| /* get pointer to destination point */ | /* get pointer to destination point */ | ||||
| pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size); | pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size); | ||||
| /* store settings */ | /* store settings */ | ||||
| copy_v2_v2_int(&pt->x, mval); | copy_v2_v2(&pt->x, mval); | ||||
| pt->pressure = pressure; | pt->pressure = pressure; | ||||
| pt->strength = 1.0f; /* unused for annotations, but initialise for easier conversions to GP Object */ | pt->strength = 1.0f; /* unused for annotations, but initialise for easier conversions to GP Object */ | ||||
| /* point time */ | /* point time */ | ||||
| pt->time = (float)(curtime - p->inittime); | pt->time = (float)(curtime - p->inittime); | ||||
| /* increment counters */ | /* increment counters */ | ||||
| gpd->runtime.sbuffer_size++; | gpd->runtime.sbuffer_size++; | ||||
| /* check if another operation can still occur */ | /* check if another operation can still occur */ | ||||
| if (gpd->runtime.sbuffer_size == GP_STROKE_BUFFER_MAX) | if (gpd->runtime.sbuffer_size == GP_STROKE_BUFFER_MAX) | ||||
| return GP_STROKEADD_FULL; | return GP_STROKEADD_FULL; | ||||
| else | else | ||||
| return GP_STROKEADD_NORMAL; | return GP_STROKEADD_NORMAL; | ||||
| } | } | ||||
| else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { | else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { | ||||
| /* get pointer to destination point */ | /* get pointer to destination point */ | ||||
| pt = (tGPspoint *)(gpd->runtime.sbuffer); | pt = (tGPspoint *)(gpd->runtime.sbuffer); | ||||
| /* store settings */ | /* store settings */ | ||||
| copy_v2_v2_int(&pt->x, mval); | copy_v2_v2(&pt->x, mval); | ||||
| pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ | pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ | ||||
| pt->strength = 1.0f; | pt->strength = 1.0f; | ||||
| pt->time = (float)(curtime - p->inittime); | pt->time = (float)(curtime - p->inittime); | ||||
| /* if there's stroke for this poly line session add (or replace last) point | /* if there's stroke for this poly line session add (or replace last) point | ||||
| * to stroke. This allows to draw lines more interactively (see new segment | * to stroke. This allows to draw lines more interactively (see new segment | ||||
| * during mouse slide, e.g.) | * during mouse slide, e.g.) | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | #define GP_SIMPLIFY_AVPOINT(offs, sfac) \ | ||||
| time += old_points[offs].time * sfac; \ | time += old_points[offs].time * sfac; \ | ||||
| } (void)0 | } (void)0 | ||||
| /* XXX Here too, do not lose start and end points! */ | /* XXX Here too, do not lose start and end points! */ | ||||
| gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time); | gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time); | ||||
| for (i = 0, j = 0; i < num_points; i++) { | for (i = 0, j = 0; i < num_points; i++) { | ||||
| if (i - j == 3) { | if (i - j == 3) { | ||||
| float co[2], pressure, time; | float co[2], pressure, time; | ||||
| int mco[2]; | float mco[2]; | ||||
| /* initialize values */ | /* initialize values */ | ||||
| co[0] = 0.0f; | co[0] = 0.0f; | ||||
| co[1] = 0.0f; | co[1] = 0.0f; | ||||
| pressure = 0.0f; | pressure = 0.0f; | ||||
| time = 0.0f; | time = 0.0f; | ||||
| /* using macro, calculate new point */ | /* using macro, calculate new point */ | ||||
| GP_SIMPLIFY_AVPOINT(j, -0.25f); | GP_SIMPLIFY_AVPOINT(j, -0.25f); | ||||
| GP_SIMPLIFY_AVPOINT(j + 1, 0.75f); | GP_SIMPLIFY_AVPOINT(j + 1, 0.75f); | ||||
| GP_SIMPLIFY_AVPOINT(j + 2, 0.75f); | GP_SIMPLIFY_AVPOINT(j + 2, 0.75f); | ||||
| GP_SIMPLIFY_AVPOINT(j + 3, -0.25f); | GP_SIMPLIFY_AVPOINT(j + 3, -0.25f); | ||||
| /* set values for adding */ | /* set values for adding */ | ||||
| mco[0] = (int)co[0]; | mco[0] = co[0]; | ||||
| mco[1] = (int)co[1]; | mco[1] = co[1]; | ||||
| /* ignore return values on this... assume to be ok for now */ | /* ignore return values on this... assume to be ok for now */ | ||||
| gp_stroke_addpoint(p, mco, pressure, p->inittime + (double)time); | gp_stroke_addpoint(p, mco, pressure, p->inittime + (double)time); | ||||
| j += 2; | j += 2; | ||||
| } | } | ||||
| } | } | ||||
| gp_stroke_addpoint( | gp_stroke_addpoint( | ||||
| ▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { | ||||
| pt->strength = ptc->strength; | pt->strength = ptc->strength; | ||||
| pt->time = ptc->time; | pt->time = ptc->time; | ||||
| } | } | ||||
| else { | else { | ||||
| float *depth_arr = NULL; | float *depth_arr = NULL; | ||||
| /* get an array of depths, far depths are blended */ | /* get an array of depths, far depths are blended */ | ||||
| if (gpencil_project_check(p)) { | if (gpencil_project_check(p)) { | ||||
| int mval[2], mval_prev[2] = { 0 }; | int mval_i[2], mval_prev[2] = { 0 }; | ||||
| int interp_depth = 0; | int interp_depth = 0; | ||||
| int found_depth = 0; | int found_depth = 0; | ||||
| depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_size, "depth_points"); | depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_size, "depth_points"); | ||||
| for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size; i++, ptc++, pt++) { | for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size; i++, ptc++, pt++) { | ||||
| copy_v2_v2_int(mval, &ptc->x); | round_v2i_v2fl(mval_i, &ptc->x); | ||||
| if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) && | if ((ED_view3d_autodist_depth(p->ar, mval_i, depth_margin, depth_arr + i) == 0) && | ||||
| (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0))) | (i && (ED_view3d_autodist_depth_seg(p->ar, mval_i, mval_prev, depth_margin + 1, depth_arr + i) == 0))) | ||||
| { | { | ||||
| interp_depth = true; | interp_depth = true; | ||||
| } | } | ||||
| else { | else { | ||||
| found_depth = true; | found_depth = true; | ||||
| } | } | ||||
| copy_v2_v2_int(mval_prev, mval); | copy_v2_v2_int(mval_prev, mval_i); | ||||
| } | } | ||||
| if (found_depth == false) { | if (found_depth == false) { | ||||
| /* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */ | /* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */ | ||||
| for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) | for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) | ||||
| depth_arr[i] = 0.9999f; | depth_arr[i] = 0.9999f; | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | |||||
| /* only erase stroke points that are visible (3d view) */ | /* only erase stroke points that are visible (3d view) */ | ||||
| static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, const int x, const int y) | static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, const int x, const int y) | ||||
| { | { | ||||
| if ((p->sa->spacetype == SPACE_VIEW3D) && | if ((p->sa->spacetype == SPACE_VIEW3D) && | ||||
| (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH)) | (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH)) | ||||
| { | { | ||||
| RegionView3D *rv3d = p->ar->regiondata; | RegionView3D *rv3d = p->ar->regiondata; | ||||
| const int mval[2] = {x, y}; | const int mval_i[2] = {x, y}; | ||||
| float mval_3d[3]; | float mval_3d[3]; | ||||
| if (ED_view3d_autodist_simple(p->ar, mval, mval_3d, 0, NULL)) { | if (ED_view3d_autodist_simple(p->ar, mval_i, mval_3d, 0, NULL)) { | ||||
| const float depth_mval = view3d_point_depth(rv3d, mval_3d); | const float depth_mval = view3d_point_depth(rv3d, mval_3d); | ||||
| const float depth_pt = view3d_point_depth(rv3d, &pt->x); | const float depth_pt = view3d_point_depth(rv3d, &pt->x); | ||||
| if (depth_pt > depth_mval) { | if (depth_pt > depth_mval) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* eraser tool - evaluation per stroke */ | /* eraser tool - evaluation per stroke */ | ||||
| /* TODO: this could really do with some optimization (KD-Tree/BVH?) */ | /* TODO: this could really do with some optimization (KD-Tree/BVH?) */ | ||||
| static void gp_stroke_eraser_dostroke( | static void gp_stroke_eraser_dostroke( | ||||
| tGPsdata *p, | tGPsdata *p, | ||||
| bGPDframe *gpf, bGPDstroke *gps, | bGPDframe *gpf, bGPDstroke *gps, | ||||
| const int mval[2], const int mvalo[2], | const float mval[2], const float mvalo[2], | ||||
| const int radius, const rcti *rect) | const int radius, const rcti *rect) | ||||
| { | { | ||||
| bGPDspoint *pt1, *pt2; | bGPDspoint *pt1, *pt2; | ||||
| int pc1[2] = {0}; | int pc1[2] = {0}; | ||||
| int pc2[2] = {0}; | int pc2[2] = {0}; | ||||
| int i; | int i; | ||||
| int mval_i[2]; | |||||
| round_v2i_v2fl(mval_i, mval); | |||||
| if (gps->totpoints == 0) { | if (gps->totpoints == 0) { | ||||
| /* just free stroke */ | /* just free stroke */ | ||||
| gp_free_stroke(gpf, gps); | gp_free_stroke(gpf, gps); | ||||
| } | } | ||||
| else if (gps->totpoints == 1) { | else if (gps->totpoints == 1) { | ||||
| /* only process if it hasn't been masked out... */ | /* only process if it hasn't been masked out... */ | ||||
| if (!(p->flags & GP_PAINTFLAG_SELECTMASK) || (gps->points->flag & GP_SPOINT_SELECT)) { | if (!(p->flags & GP_PAINTFLAG_SELECTMASK) || (gps->points->flag & GP_SPOINT_SELECT)) { | ||||
| gp_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]); | gp_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]); | ||||
| /* do boundbox check first */ | /* do boundbox check first */ | ||||
| if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) { | if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) { | ||||
| /* only check if point is inside */ | /* only check if point is inside */ | ||||
| if (len_v2v2_int(mval, pc1) <= radius) { | if (len_v2v2_int(mval_i, pc1) <= radius) { | ||||
antoniov: Maybe you could calc mval_i at the begining of the function. | |||||
| /* free stroke */ | /* free stroke */ | ||||
| gp_free_stroke(gpf, gps); | gp_free_stroke(gpf, gps); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Perform culling? */ | /* Perform culling? */ | ||||
| Show All 34 Lines | for (i = 0; (i + 1) < gps->totpoints; i++) { | ||||
| * eraser region (either within stroke painted, or on its lines) | * eraser region (either within stroke painted, or on its lines) | ||||
| * - this assumes that linewidth is irrelevant | * - this assumes that linewidth is irrelevant | ||||
| */ | */ | ||||
| if (gp_stroke_inside_circle(mval, mvalo, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { | if (gp_stroke_inside_circle(mval, mvalo, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { | ||||
| if ((gp_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) || | if ((gp_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) || | ||||
| (gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) | (gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) | ||||
| { | { | ||||
| /* Edge is affected - Check individual points now */ | /* Edge is affected - Check individual points now */ | ||||
| if (len_v2v2_int(mval, pc1) <= radius) { | if (len_v2v2_int(mval_i, pc1) <= radius) { | ||||
| pt1->flag |= GP_SPOINT_TAG; | pt1->flag |= GP_SPOINT_TAG; | ||||
| } | } | ||||
| if (len_v2v2_int(mval, pc2) <= radius) { | if (len_v2v2_int(mval_i, pc2) <= radius) { | ||||
| pt2->flag |= GP_SPOINT_TAG; | pt2->flag |= GP_SPOINT_TAG; | ||||
| } | } | ||||
| do_cull = true; | do_cull = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,463 Lines • Show Last 20 Lines | |||||
Maybe you could calc mval_i at the begining of the function.