static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2]) { Paint *p = BKE_paint_get_active_from_context(C); Brush *br = p->brush; Main *bmain = CTX_data_main(C); PaintCurve *pc; PaintCurvePoint *pcp; wmWindow *window = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); float vec[3] = {loc[0], loc[1], 0.0}; int add_index; int i; pc = br->paint_curve; if (!pc) { br->paint_curve = pc = BKE_paint_curve_add(bmain, "PaintCurve"); } ED_paintcurve_undo_push_begin(op->type->name); pcp = MEM_mallocN((pc->tot_points + 1) * sizeof(PaintCurvePoint), "PaintCurvePoint"); add_index = pc->add_index; if (pc->points) { if (add_index > 0) memcpy(pcp, pc->points, add_index * sizeof(PaintCurvePoint)); if (add_index < pc->tot_points) memcpy(pcp + add_index + 1, pc->points + add_index, (pc->tot_points - add_index) * sizeof(PaintCurvePoint)); MEM_freeN(pc->points); } pc->points = pcp; pc->tot_points++; /* initialize new point */ memset(&pcp[add_index], 0, sizeof(PaintCurvePoint)); copy_v3_v3(pcp[add_index].bez.vec[0], vec); copy_v3_v3(pcp[add_index].bez.vec[1], vec); copy_v3_v3(pcp[add_index].bez.vec[2], vec); /* last step, clear selection from all bezier handles expect the next */ for (i = 0; i < pc->tot_points; i++) { pcp[i].bez.f1 = pcp[i].bez.f2 = pcp[i].bez.f3 = 0; } BKE_paint_curve_clamp_endpoint_add_index(pc, add_index); if (pc->add_index != 0) { pcp[add_index].bez.f3 = SELECT; pcp[add_index].bez.h2 = HD_ALIGN; } else { pcp[add_index].bez.f1 = SELECT; pcp[add_index].bez.h1 = HD_ALIGN; } ED_paintcurve_undo_push_end(); WM_paint_cursor_tag_redraw(window, ar); }
static int paintcurve_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) { PointSlideData *psd = op->customdata; if (event->type == psd->event && event->val == KM_RELEASE) { MEM_freeN(psd); ED_paintcurve_undo_push_begin(op->type->name); ED_paintcurve_undo_push_end(); return OPERATOR_FINISHED; } switch (event->type) { case MOUSEMOVE: { ARegion *ar = CTX_wm_region(C); wmWindow *window = CTX_wm_window(C); float diff[2] = { event->mval[0] - psd->initial_loc[0], event->mval[1] - psd->initial_loc[1]}; if (psd->select == 1) { int i; for (i = 0; i < 3; i++) add_v2_v2v2(psd->pcp->bez.vec[i], diff, psd->point_initial_loc[i]); } else { add_v2_v2(diff, psd->point_initial_loc[psd->select]); copy_v2_v2(psd->pcp->bez.vec[psd->select], diff); if (psd->align) { char opposite = (psd->select == 0) ? 2 : 0; sub_v2_v2v2(diff, psd->pcp->bez.vec[1], psd->pcp->bez.vec[psd->select]); add_v2_v2v2(psd->pcp->bez.vec[opposite], psd->pcp->bez.vec[1], diff); } } WM_paint_cursor_tag_redraw(window, ar); break; } default: break; } return OPERATOR_RUNNING_MODAL; }
static bool paintcurve_point_select( bContext *C, wmOperator *op, const int loc[2], bool toggle, bool extend) { wmWindow *window = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); Paint *p = BKE_paint_get_active_from_context(C); Brush *br = p->brush; PaintCurve *pc; int i; const float loc_fl[2] = {UNPACK2(loc)}; pc = br->paint_curve; if (!pc) { return false; } ED_paintcurve_undo_push_begin(op->type->name); if (toggle) { PaintCurvePoint *pcp; char select = 0; bool selected = false; pcp = pc->points; for (i = 0; i < pc->tot_points; i++) { if (pcp[i].bez.f1 || pcp[i].bez.f2 || pcp[i].bez.f3) { selected = true; break; } } if (!selected) { select = SELECT; } for (i = 0; i < pc->tot_points; i++) { pc->points[i].bez.f1 = pc->points[i].bez.f2 = pc->points[i].bez.f3 = select; } } else { PaintCurvePoint *pcp; char selflag; pcp = paintcurve_point_get_closest(pc, loc_fl, false, PAINT_CURVE_SELECT_THRESHOLD, &selflag); if (pcp) { BKE_paint_curve_clamp_endpoint_add_index(pc, pcp - pc->points); if (selflag == SEL_F2) { if (extend) { pcp->bez.f2 ^= SELECT; } else { pcp->bez.f2 |= SELECT; } } else if (selflag == SEL_F1) { if (extend) { pcp->bez.f1 ^= SELECT; } else { pcp->bez.f1 |= SELECT; } } else if (selflag == SEL_F3) { if (extend) { pcp->bez.f3 ^= SELECT; } else { pcp->bez.f3 |= SELECT; } } } /* clear selection for unselected points if not extending and if a point has been selected */ if (!extend && pcp) { for (i = 0; i < pc->tot_points; i++) { pc->points[i].bez.f1 = pc->points[i].bez.f2 = pc->points[i].bez.f3 = 0; if ((pc->points + i) == pcp) { char index = paintcurve_point_co_index(selflag); PAINT_CURVE_POINT_SELECT(pcp, index); } } } if (!pcp) { ED_paintcurve_undo_push_end(); return false; } } ED_paintcurve_undo_push_end(); WM_paint_cursor_tag_redraw(window, ar); return true; }
static int paintcurve_delete_point_exec(bContext *C, wmOperator *op) { Paint *p = BKE_paint_get_active_from_context(C); Brush *br = p->brush; PaintCurve *pc; PaintCurvePoint *pcp; wmWindow *window = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); int i; int tot_del = 0; pc = br->paint_curve; if (!pc || pc->tot_points == 0) { return OPERATOR_CANCELLED; } ED_paintcurve_undo_push_begin(op->type->name); #define DELETE_TAG 2 for (i = 0, pcp = pc->points; i < pc->tot_points; i++, pcp++) { if (BEZT_ISSEL_ANY(&pcp->bez)) { pcp->bez.f2 |= DELETE_TAG; tot_del++; } } if (tot_del > 0) { int j = 0; int new_tot = pc->tot_points - tot_del; PaintCurvePoint *points_new = NULL; if (new_tot > 0) { points_new = MEM_mallocN(new_tot * sizeof(PaintCurvePoint), "PaintCurvePoint"); } for (i = 0, pcp = pc->points; i < pc->tot_points; i++, pcp++) { if (!(pcp->bez.f2 & DELETE_TAG)) { points_new[j] = pc->points[i]; if ((i + 1) == pc->add_index) { BKE_paint_curve_clamp_endpoint_add_index(pc, j); } j++; } else if ((i + 1) == pc->add_index) { /* prefer previous point */ pc->add_index = j; } } MEM_freeN(pc->points); pc->points = points_new; pc->tot_points = new_tot; } #undef DELETE_TAG ED_paintcurve_undo_push_end(); WM_paint_cursor_tag_redraw(window, ar); return OPERATOR_FINISHED; }