diff options
author | Charlie Jolly <mistajolly@gmail.com> | 2018-12-04 18:21:09 +0300 |
---|---|---|
committer | Charlie Jolly <mistajolly@gmail.com> | 2018-12-05 18:59:23 +0300 |
commit | 94503efb126526a31d62be6363d8562651f43f0a (patch) | |
tree | beded5f1c71dd8b76490e1dd362602babedb2160 | |
parent | cdf626615d99f3a73ba453f0ebcada88d20ca8bb (diff) |
GP: Fix precision issue with Circle and Arc tools
Differential Revision: https://developer.blender.org/D4030
-rw-r--r-- | source/blender/editors/gpencil/gpencil_intern.h | 7 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_primitive.c | 51 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_utils.c | 35 | ||||
-rw-r--r-- | source/blender/editors/include/ED_gpencil.h | 13 |
4 files changed, 80 insertions, 26 deletions
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 5db5c0f2571..6d05afa0e8d 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -228,6 +228,13 @@ void gp_stroke_convertcoords_tpoint( bGPDlayer *gpl, const struct tGPspoint *point2D, float *depth, float out[3]); +/* helper to convert 2d to 3d for primitive. See: D4030 */ +void gp_stroke_convertcoords_tpoint_primitive( + struct Scene *scene, struct ARegion *ar, + struct Object *ob, + bGPDlayer *gpl, const struct tPGPspoint *point2D, + float out[3]); + /* Poll Callbacks ------------------------------------ */ /* gpencil_utils.c */ diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index d22e9736172..9d36c1f3963 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -260,37 +260,37 @@ static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi /* ----------------------- */ /* create a rectangle */ -static void gp_primitive_rectangle(tGPDprimitive *tgpi, tGPspoint *points2D) +static void gp_primitive_rectangle(tGPDprimitive *tgpi, tPGPspoint *points2D) { BLI_assert(tgpi->tot_edges == 4); - points2D[0].x = tgpi->top[0]; - points2D[0].y = tgpi->top[1]; + points2D[0].x = (float)tgpi->top[0]; + points2D[0].y = (float)tgpi->top[1]; - points2D[1].x = tgpi->bottom[0]; - points2D[1].y = tgpi->top[1]; + points2D[1].x = (float)tgpi->bottom[0]; + points2D[1].y = (float)tgpi->top[1]; - points2D[2].x = tgpi->bottom[0]; - points2D[2].y = tgpi->bottom[1]; + points2D[2].x = (float)tgpi->bottom[0]; + points2D[2].y = (float)tgpi->bottom[1]; - points2D[3].x = tgpi->top[0]; - points2D[3].y = tgpi->bottom[1]; + points2D[3].x = (float)tgpi->top[0]; + points2D[3].y = (float)tgpi->bottom[1]; } /* create a line */ -static void gp_primitive_line(tGPDprimitive *tgpi, tGPspoint *points2D) +static void gp_primitive_line(tGPDprimitive *tgpi, tPGPspoint *points2D) { BLI_assert(tgpi->tot_edges == 2); - points2D[0].x = tgpi->top[0]; - points2D[0].y = tgpi->top[1]; + points2D[0].x = (float)tgpi->top[0]; + points2D[0].y = (float)tgpi->top[1]; - points2D[1].x = tgpi->bottom[0]; - points2D[1].y = tgpi->bottom[1]; + points2D[1].x = (float)tgpi->bottom[0]; + points2D[1].y = (float)tgpi->bottom[1]; } /* create an arc */ -static void gp_primitive_arc(tGPDprimitive *tgpi, tGPspoint *points2D) +static void gp_primitive_arc(tGPDprimitive *tgpi, tPGPspoint *points2D) { const int totpoints = tgpi->tot_edges; const float step = M_PI_2 / (float)(totpoints - 1); @@ -313,15 +313,15 @@ static void gp_primitive_arc(tGPDprimitive *tgpi, tGPspoint *points2D) length[1] = end[1] - start[1]; for (int i = 0; i < totpoints; i++) { - tGPspoint *p2d = &points2D[i]; - p2d->x = (int)(start[0] + sinf(a) * length[0]); - p2d->y = (int)(end[1] - cosf(a) * length[1]); + tPGPspoint *p2d = &points2D[i]; + p2d->x = (start[0] + sinf(a) * length[0]); + p2d->y = (end[1] - cosf(a) * length[1]); a += step; } } /* create a circle */ -static void gp_primitive_circle(tGPDprimitive *tgpi, tGPspoint *points2D) +static void gp_primitive_circle(tGPDprimitive *tgpi, tPGPspoint *points2D) { const int totpoints = tgpi->tot_edges; const float step = (2.0f * M_PI) / (float)(totpoints); @@ -336,10 +336,9 @@ static void gp_primitive_circle(tGPDprimitive *tgpi, tGPspoint *points2D) radius[1] = fabsf(((tgpi->bottom[1] - tgpi->top[1]) / 2.0f)); for (int i = 0; i < totpoints; i++) { - tGPspoint *p2d = &points2D[i]; - - p2d->x = (int)(center[0] + cosf(a) * radius[0]); - p2d->y = (int)(center[1] + sinf(a) * radius[1]); + tPGPspoint *p2d = &points2D[i]; + p2d->x = (center[0] + cosf(a) * radius[0]); + p2d->y = (center[1] + sinf(a) * radius[1]); a += step; } } @@ -360,7 +359,7 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) gps->totpoints = tgpi->tot_edges; /* compute screen-space coordinates for points */ - tGPspoint *points2D = MEM_callocN(sizeof(tGPspoint) * tgpi->tot_edges, "gp primitive points2D"); + tPGPspoint *points2D = MEM_callocN(sizeof(tPGPspoint) * tgpi->tot_edges, "gp primitive points2D"); switch (tgpi->type) { case GP_STROKE_BOX: gp_primitive_rectangle(tgpi, points2D); @@ -385,10 +384,10 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) /* convert screen-coordinates to 3D coordinates */ for (int i = 0; i < gps->totpoints; i++) { bGPDspoint *pt = &gps->points[i]; - tGPspoint *p2d = &points2D[i]; + tPGPspoint *p2d = &points2D[i]; /* convert screen-coordinates to 3D coordinates */ - gp_stroke_convertcoords_tpoint(tgpi->scene, tgpi->ar, tgpi->ob, tgpi->gpl, p2d, NULL, &pt->x); + gp_stroke_convertcoords_tpoint_primitive(tgpi->scene, tgpi->ar, tgpi->ob, tgpi->gpl, p2d, &pt->x); pt->pressure = 1.0f; pt->strength = tgpi->brush->gpencil_settings->draw_strength; diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 73be10a537f..4d16f842fa3 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -807,6 +807,41 @@ void gp_stroke_convertcoords_tpoint( } /** + * Convert primitive tPGPspoint (temporary 2D/screenspace point data used by GP primitive operators) + * to 3D coordinates. + * + * See: D4030 + */ +void gp_stroke_convertcoords_tpoint_primitive( + Scene *scene, ARegion *ar, + Object *ob, bGPDlayer *gpl, + const tPGPspoint *point2D, + float r_out[3]) +{ + ToolSettings *ts = scene->toolsettings; + + float mval_f[2] = { point2D->x, point2D->y }; + float mval_prj[2]; + float rvec[3], dvec[3]; + float zfac; + + /* Current method just converts each point in screen-coordinates to + * 3D-coordinates using the 3D-cursor as reference. + */ + ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, rvec); + zfac = ED_view3d_calc_zfac(ar->regiondata, rvec, NULL); + + if (ED_view3d_project_float_global(ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + sub_v2_v2v2(mval_f, mval_prj, mval_f); + ED_view3d_win_to_delta(ar, mval_f, dvec, zfac); + sub_v3_v3v3(r_out, rvec, dvec); + } + else { + zero_v3(r_out); + } +} + +/** * Get drawing reference point for conversion or projection of the stroke * \param[out] r_vec : Reference point found */ diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 850969cce96..b23f5afef52 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -81,6 +81,19 @@ typedef struct tGPspoint { float uv_rot; /* uv rotation for dor mode */ } tGPspoint; +/* Temporary 'Stroke Point' data (2D / screen-space) + * + * Used for primitives. See: D4030 + */ +typedef struct tPGPspoint { + float x, y; /* x and y coordinates of cursor (in relative to area) */ + float pressure; /* pressure of tablet at this point */ + float strength; /* pressure of tablet at this point for alpha factor */ + float time; /* Time relative to stroke start (used when converting to path) */ + float uv_fac; /* factor of uv along the stroke */ + float uv_rot; /* uv rotation for dor mode */ +} tPGPspoint; + /* used to sort by zdepth gpencil objects in viewport */ /* TODO: this could be a system parameter in userprefs screen */ #define GP_CACHE_BLOCK_SIZE 16 |