예제 #1
0
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);
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}