Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/gpencil/gpencil_convert.c
| Show First 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* --- */ | /* --- */ | ||||
| /* convert the coordinates from the given stroke point into 3d-coordinates | /* convert the coordinates from the given stroke point into 3d-coordinates | ||||
| * - assumes that the active space is the 3D-View | * - assumes that the active space is the 3D-View | ||||
| */ | */ | ||||
| static void gp_strokepoint_convertcoords( | static void gp_strokepoint_convertcoords( | ||||
| bContext *C, bGPDlayer *gpl, bGPDstroke *gps, bGPDspoint *source_pt, | bContext *C, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, bGPDspoint *source_pt, | ||||
| float p3d[3], const rctf *subrect) | float p3d[3], const rctf *subrect) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| Object *obact = CTX_data_active_object(C); | |||||
| bGPDspoint mypt, *pt; | bGPDspoint mypt, *pt; | ||||
| float diff_mat[4][4]; | float diff_mat[4][4]; | ||||
| pt = &mypt; | pt = &mypt; | ||||
| /* calculate difference matrix if parent object */ | |||||
| if (gpl->parent == NULL) { | |||||
| copy_v3_v3(&pt->x, &source_pt->x); | |||||
| } | |||||
| else { | |||||
| /* apply parent transform */ | /* apply parent transform */ | ||||
| float fpt[3]; | float fpt[3]; | ||||
| ED_gpencil_parent_location(gpl, diff_mat); | ED_gpencil_parent_location(obact, gpd, gpl, diff_mat); | ||||
| mul_v3_m4v3(fpt, diff_mat, &source_pt->x); | mul_v3_m4v3(fpt, diff_mat, &source_pt->x); | ||||
| copy_v3_v3(&pt->x, fpt); | copy_v3_v3(&pt->x, fpt); | ||||
| } | |||||
| if (gps->flag & GP_STROKE_3DSPACE) { | if (gps->flag & GP_STROKE_3DSPACE) { | ||||
| /* directly use 3d-coordinates */ | /* directly use 3d-coordinates */ | ||||
| copy_v3_v3(p3d, &pt->x); | copy_v3_v3(p3d, &pt->x); | ||||
| } | } | ||||
| else { | else { | ||||
| const float *fp = ED_view3d_cursor3d_get(scene, v3d); | const float *fp = ED_view3d_cursor3d_get(scene, v3d); | ||||
| ▲ Show 20 Lines • Show All 402 Lines • ▼ Show 20 Lines | static void gp_stroke_to_path_add_point(tGpTimingData *gtd, BPoint *bp, const float p[3], const float prev_p[3], | ||||
| } | } | ||||
| /* Update timing data */ | /* Update timing data */ | ||||
| if (do_gtd) { | if (do_gtd) { | ||||
| gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p)); | gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p)); | ||||
| } | } | ||||
| } | } | ||||
| static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, | static void gp_stroke_to_path(bContext *C, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, | ||||
| float minmax_weights[2], const float rad_fac, bool stitch, const bool add_start_point, | float minmax_weights[2], const float rad_fac, bool stitch, const bool add_start_point, | ||||
| const bool add_end_point, tGpTimingData *gtd) | const bool add_end_point, tGpTimingData *gtd) | ||||
| { | { | ||||
| bGPDspoint *pt; | bGPDspoint *pt; | ||||
| Nurb *nu = (curnu) ? *curnu : NULL; | Nurb *nu = (curnu) ? *curnu : NULL; | ||||
| BPoint *bp, *prev_bp = NULL; | BPoint *bp, *prev_bp = NULL; | ||||
| const bool do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE); | const bool do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE); | ||||
| const int add_start_end_points = (add_start_point ? 1 : 0) + (add_end_point ? 1 : 0); | const int add_start_end_points = (add_start_point ? 1 : 0) + (add_end_point ? 1 : 0); | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (curnu && !stitch && old_nbp) { | ||||
| prev_bp = NULL; | prev_bp = NULL; | ||||
| if ((old_nbp > 1) && (gps->prev->totpoints > 1)) { | if ((old_nbp > 1) && (gps->prev->totpoints > 1)) { | ||||
| /* Only use last curve segment if previous stroke was not a single-point one! */ | /* Only use last curve segment if previous stroke was not a single-point one! */ | ||||
| prev_bp = &nu->bp[old_nbp - 2]; | prev_bp = &nu->bp[old_nbp - 2]; | ||||
| } | } | ||||
| bp = &nu->bp[old_nbp - 1]; | bp = &nu->bp[old_nbp - 1]; | ||||
| /* First point */ | /* First point */ | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points, p, subrect); | ||||
| if (prev_bp) { | if (prev_bp) { | ||||
| interp_v3_v3v3(p1, bp->vec, prev_bp->vec, -GAP_DFAC); | interp_v3_v3v3(p1, bp->vec, prev_bp->vec, -GAP_DFAC); | ||||
| if (do_gtd) { | if (do_gtd) { | ||||
| const int idx = gps->prev->totpoints - 1; | const int idx = gps->prev->totpoints - 1; | ||||
| dt1 = interpf(gps->prev->points[idx - 1].time, gps->prev->points[idx].time, -GAP_DFAC); | dt1 = interpf(gps->prev->points[idx - 1].time, gps->prev->points[idx].time, -GAP_DFAC); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| interp_v3_v3v3(p1, bp->vec, p, GAP_DFAC); | interp_v3_v3v3(p1, bp->vec, p, GAP_DFAC); | ||||
| if (do_gtd) { | if (do_gtd) { | ||||
| dt1 = interpf(gps->inittime - gps->prev->inittime, 0.0f, GAP_DFAC); | dt1 = interpf(gps->inittime - gps->prev->inittime, 0.0f, GAP_DFAC); | ||||
| } | } | ||||
| } | } | ||||
| bp++; | bp++; | ||||
| gp_stroke_to_path_add_point(gtd, bp, p1, (bp - 1)->vec, do_gtd, gps->prev->inittime, dt1, | gp_stroke_to_path_add_point(gtd, bp, p1, (bp - 1)->vec, do_gtd, gps->prev->inittime, dt1, | ||||
| 0.0f, rad_fac, minmax_weights); | 0.0f, rad_fac, minmax_weights); | ||||
| /* Second point */ | /* Second point */ | ||||
| /* Note dt2 is always negative, which marks the gap. */ | /* Note dt2 is always negative, which marks the gap. */ | ||||
| if (gps->totpoints > 1) { | if (gps->totpoints > 1) { | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points + 1, next_p, subrect); | ||||
| interp_v3_v3v3(p2, p, next_p, -GAP_DFAC); | interp_v3_v3v3(p2, p, next_p, -GAP_DFAC); | ||||
| if (do_gtd) { | if (do_gtd) { | ||||
| dt2 = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC); | dt2 = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| interp_v3_v3v3(p2, p, bp->vec, GAP_DFAC); | interp_v3_v3v3(p2, p, bp->vec, GAP_DFAC); | ||||
| if (do_gtd) { | if (do_gtd) { | ||||
| dt2 = interpf(gps->prev->inittime - gps->inittime, 0.0f, GAP_DFAC); | dt2 = interpf(gps->prev->inittime - gps->inittime, 0.0f, GAP_DFAC); | ||||
| } | } | ||||
| } | } | ||||
| bp++; | bp++; | ||||
| gp_stroke_to_path_add_point(gtd, bp, p2, p1, do_gtd, gps->inittime, dt2, 0.0f, rad_fac, minmax_weights); | gp_stroke_to_path_add_point(gtd, bp, p2, p1, do_gtd, gps->inittime, dt2, 0.0f, rad_fac, minmax_weights); | ||||
| old_nbp += 2; | old_nbp += 2; | ||||
| } | } | ||||
| else if (add_start_point) { | else if (add_start_point) { | ||||
| float p[3], next_p[3]; | float p[3], next_p[3]; | ||||
| float dt = 0.0f; | float dt = 0.0f; | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points, p, subrect); | ||||
| if (gps->totpoints > 1) { | if (gps->totpoints > 1) { | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points + 1, next_p, subrect); | ||||
| interp_v3_v3v3(p, p, next_p, -GAP_DFAC); | interp_v3_v3v3(p, p, next_p, -GAP_DFAC); | ||||
| if (do_gtd) { | if (do_gtd) { | ||||
| dt = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC); | dt = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| p[0] -= GAP_DFAC; /* Rather arbitrary... */ | p[0] -= GAP_DFAC; /* Rather arbitrary... */ | ||||
| dt = -GAP_DFAC; /* Rather arbitrary too! */ | dt = -GAP_DFAC; /* Rather arbitrary too! */ | ||||
| Show All 15 Lines | static void gp_stroke_to_path(bContext *C, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, | ||||
| for (i = (stitch) ? 1 : 0, pt = &gps->points[(stitch) ? 1 : 0], bp = &nu->bp[old_nbp]; | for (i = (stitch) ? 1 : 0, pt = &gps->points[(stitch) ? 1 : 0], bp = &nu->bp[old_nbp]; | ||||
| i < gps->totpoints; | i < gps->totpoints; | ||||
| i++, pt++, bp++) | i++, pt++, bp++) | ||||
| { | { | ||||
| float p[3]; | float p[3]; | ||||
| float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC; | float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC; | ||||
| /* get coordinates to add at */ | /* get coordinates to add at */ | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, pt, p, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt, p, subrect); | ||||
| gp_stroke_to_path_add_point(gtd, bp, p, (prev_bp) ? prev_bp->vec : p, do_gtd, gps->inittime, pt->time, | gp_stroke_to_path_add_point(gtd, bp, p, (prev_bp) ? prev_bp->vec : p, do_gtd, gps->inittime, pt->time, | ||||
| width, rad_fac, minmax_weights); | width, rad_fac, minmax_weights); | ||||
| prev_bp = bp; | prev_bp = bp; | ||||
| } | } | ||||
| if (add_end_point) { | if (add_end_point) { | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd, BezTriple *bezt, | ||||
| } | } | ||||
| /* Update timing data */ | /* Update timing data */ | ||||
| if (do_gtd) { | if (do_gtd) { | ||||
| gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p)); | gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p)); | ||||
| } | } | ||||
| } | } | ||||
| static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, | static void gp_stroke_to_bezier(bContext *C, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, | ||||
| float minmax_weights[2], const float rad_fac, bool stitch, const bool add_start_point, | float minmax_weights[2], const float rad_fac, bool stitch, const bool add_start_point, | ||||
| const bool add_end_point, tGpTimingData *gtd) | const bool add_end_point, tGpTimingData *gtd) | ||||
| { | { | ||||
| bGPDspoint *pt; | bGPDspoint *pt; | ||||
| Nurb *nu = (curnu) ? *curnu : NULL; | Nurb *nu = (curnu) ? *curnu : NULL; | ||||
| BezTriple *bezt, *prev_bezt = NULL; | BezTriple *bezt, *prev_bezt = NULL; | ||||
| int i, tot, old_nbezt = 0; | int i, tot, old_nbezt = 0; | ||||
| const int add_start_end_points = (add_start_point ? 1 : 0) + (add_end_point ? 1 : 0); | const int add_start_end_points = (add_start_point ? 1 : 0) + (add_end_point ? 1 : 0); | ||||
| Show All 25 Lines | if (do_gtd) { | ||||
| gp_timing_data_set_nbr(gtd, nu->pntsu); | gp_timing_data_set_nbr(gtd, nu->pntsu); | ||||
| } | } | ||||
| tot = gps->totpoints; | tot = gps->totpoints; | ||||
| /* get initial coordinates */ | /* get initial coordinates */ | ||||
| pt = gps->points; | pt = gps->points; | ||||
| if (tot) { | if (tot) { | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect); | ||||
| if (tot > 1) { | if (tot > 1) { | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect); | ||||
| } | } | ||||
| if (stitch && tot > 2) { | if (stitch && tot > 2) { | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 2, p3d_next, subrect); | ||||
| } | } | ||||
| } | } | ||||
| /* If needed, make the link between both strokes with two zero-radius additional points */ | /* If needed, make the link between both strokes with two zero-radius additional points */ | ||||
| if (curnu && old_nbezt) { | if (curnu && old_nbezt) { | ||||
| BLI_assert(gps->prev != NULL); | BLI_assert(gps->prev != NULL); | ||||
| /* Update last point's second handle */ | /* Update last point's second handle */ | ||||
| ▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | for (i = stitch ? 1 : 0, bezt = &nu->bezt[old_nbezt]; i < tot; i++, pt++, bezt++) { | ||||
| gp_stroke_to_bezier_add_point(gtd, bezt, p3d_cur, h1, h2, prev_bezt ? prev_bezt->vec[1] : p3d_cur, | gp_stroke_to_bezier_add_point(gtd, bezt, p3d_cur, h1, h2, prev_bezt ? prev_bezt->vec[1] : p3d_cur, | ||||
| do_gtd, gps->inittime, pt->time, width, rad_fac, minmax_weights); | do_gtd, gps->inittime, pt->time, width, rad_fac, minmax_weights); | ||||
| /* shift coord vects */ | /* shift coord vects */ | ||||
| copy_v3_v3(p3d_prev, p3d_cur); | copy_v3_v3(p3d_prev, p3d_cur); | ||||
| copy_v3_v3(p3d_cur, p3d_next); | copy_v3_v3(p3d_cur, p3d_next); | ||||
| if (i + 2 < tot) { | if (i + 2 < tot) { | ||||
| gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect); | gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 2, p3d_next, subrect); | ||||
| } | } | ||||
| prev_bezt = bezt; | prev_bezt = bezt; | ||||
| } | } | ||||
| if (add_end_point) { | if (add_end_point) { | ||||
| float p[3]; | float p[3]; | ||||
| float dt = 0.0f; | float dt = 0.0f; | ||||
| ▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | for (gps = gpf->strokes.first; gps; gps = gps->next) { | ||||
| /* Decide whether we connect this stroke to previous one */ | /* Decide whether we connect this stroke to previous one */ | ||||
| if (!(stitch || link_strokes)) { | if (!(stitch || link_strokes)) { | ||||
| nu = NULL; | nu = NULL; | ||||
| } | } | ||||
| switch (mode) { | switch (mode) { | ||||
| case GP_STROKECONVERT_PATH: | case GP_STROKECONVERT_PATH: | ||||
| gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, | gp_stroke_to_path(C, gpd, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, | ||||
| add_start_point, add_end_point, gtd); | add_start_point, add_end_point, gtd); | ||||
| break; | break; | ||||
| case GP_STROKECONVERT_CURVE: | case GP_STROKECONVERT_CURVE: | ||||
| case GP_STROKECONVERT_POLY: /* convert after */ | case GP_STROKECONVERT_POLY: /* convert after */ | ||||
| gp_stroke_to_bezier(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, | gp_stroke_to_bezier(C, gpd, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, | ||||
| add_start_point, add_end_point, gtd); | add_start_point, add_end_point, gtd); | ||||
| break; | break; | ||||
| default: | default: | ||||
| BLI_assert(!"invalid mode"); | BLI_assert(!"invalid mode"); | ||||
| break; | break; | ||||
| } | } | ||||
| prev_gps = gps; | prev_gps = gps; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 307 Lines • Show Last 20 Lines | |||||