Esempio n. 1
0
static int set_handle_type_exec(bContext *C, wmOperator *op)
{
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	int handle_type = RNA_enum_get(op->ptr, "type");

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;
		int i;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *point = &spline->points[i];

				if (MASKPOINT_ISSEL_ANY(point)) {
					BezTriple *bezt = &point->bezt;

					bezt->h1 = bezt->h2 = handle_type;
				}
			}
		}
	}

	WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
	DAG_id_tag_update(&mask->id, 0);

	return OPERATOR_FINISHED;
}
static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;
		int i;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *point = &spline->points[i];

				if (MASKPOINT_ISSEL_ANY(point)) {
					point->parent.id = NULL;
				}
			}
		}
	}

	WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
	DAG_id_tag_update(&mask->id, 0);

	return OPERATOR_FINISHED;
}
Esempio n. 3
0
static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, MaskSplinePoint **point, bool check_active)
{
	MaskSpline *cur_spline = masklay->splines.first;

	*spline = NULL;
	*point = NULL;

	if (check_active) {
		/* TODO, having an active point but no active spline is possible, why? */
		if (masklay->act_spline && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) {
			*spline = masklay->act_spline;
			*point = masklay->act_point;
			return;
		}
	}

	while (cur_spline) {
		int i;

		for (i = 0; i < cur_spline->tot_point; i++) {
			MaskSplinePoint *cur_point = &cur_spline->points[i];

			if (MASKPOINT_ISSEL_ANY(cur_point)) {
				if (*spline != NULL && *spline != cur_spline) {
					*spline = NULL;
					*point = NULL;
					return;
				}
				else if (*point) {
					*point = NULL;
				}
				else {
					*spline = cur_spline;
					*point = cur_point;
				}
			}
		}

		cur_spline = cur_spline->next;
	}
}
Esempio n. 4
0
/* 'check' select */
bool ED_mask_spline_select_check(MaskSpline *spline)
{
	int i;

	for (i = 0; i < spline->tot_point; i++) {
		MaskSplinePoint *point = &spline->points[i];

		if (MASKPOINT_ISSEL_ANY(point))
			return true;
	}

	return false;
}
Esempio n. 5
0
/* *** recalc normals *** */
static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	int i;

	bool changed = false;

	/* do actual selection */
	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;
		bool changed_layer = false;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *point = &spline->points[i];

				if (MASKPOINT_ISSEL_ANY(point)) {
					BKE_mask_calc_handle_point_auto(spline, point, FALSE);
					changed = true;
					changed_layer = true;
				}
			}
		}

		if (changed_layer) {
			if (IS_AUTOKEY_ON(scene)) {
				ED_mask_layer_shape_auto_key(masklay, CFRA);
			}
		}
	}

	if (changed) {
		/* TODO: only update this spline */
		BKE_mask_update_display(mask, CFRA);

		WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
		WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);

		return OPERATOR_FINISHED;
	}

	return OPERATOR_CANCELLED;
}
Esempio n. 6
0
static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	bool changed = false;
	int i;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;

		if (masklay->restrictflag & (MASK_RESTRICT_SELECT | MASK_RESTRICT_VIEW)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *point = &spline->points[i];

				if (MASKPOINT_ISSEL_ANY(point)) {
					BezTriple *bezt = &point->bezt;
					bezt->weight = 0.0f;
					changed = true;
				}
			}
		}
	}

	if (changed) {
		/* TODO: only update edited splines */
		BKE_mask_update_display(mask, CFRA);

		WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask);
		DAG_id_tag_update(&mask->id, 0);

		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
Esempio n. 7
0
static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
	SlidePointData *slidedata = slide_point_customdata(C, op, event);

	if (slidedata) {
		Mask *mask = CTX_data_edit_mask(C);

		op->customdata = slidedata;

		WM_event_add_modal_handler(C, op);

#if 0
		if (slidedata->uw) {
			if ((slidedata->uw->flag & SELECT) == 0) {
				ED_mask_select_toggle_all(mask, SEL_DESELECT);

				slidedata->uw->flag |= SELECT;

				ED_mask_select_flush_all(mask);
			}
		}
		else if (!MASKPOINT_ISSEL_ANY(slidedata->point)) {
			ED_mask_select_toggle_all(mask, SEL_DESELECT);

			BKE_mask_point_select_set(slidedata->point, TRUE);

			ED_mask_select_flush_all(mask);
		}
#endif

		slidedata->masklay->act_spline = slidedata->spline;
		slidedata->masklay->act_point = slidedata->point;

		WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);

		return OPERATOR_RUNNING_MODAL;
	}

	return OPERATOR_PASS_THROUGH;
}
Esempio n. 8
0
void ED_mask_select_toggle_all(Mask *mask, int action)
{
	MaskLayer *masklay;

	if (action == SEL_TOGGLE) {
		if (ED_mask_select_check(mask))
			action = SEL_DESELECT;
		else
			action = SEL_SELECT;
	}

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {

		if (masklay->restrictflag & MASK_RESTRICT_VIEW) {
			continue;
		}

		if (action == SEL_INVERT) {
			/* we don't have generic functions for this, its restricted to this operator
			 * if one day we need to re-use such functionality, they can be split out */

			MaskSpline *spline;
			if (masklay->restrictflag & MASK_RESTRICT_SELECT) {
				continue;
			}
			for (spline = masklay->splines.first; spline; spline = spline->next) {
				int i;
				for (i = 0; i < spline->tot_point; i++) {
					MaskSplinePoint *point = &spline->points[i];
					BKE_mask_point_select_set(point, !MASKPOINT_ISSEL_ANY(point));
				}
			}

		}
		else {
			ED_mask_layer_select_set(masklay, (action == SEL_SELECT) ? true : false);
		}
	}
}
Esempio n. 9
0
void ED_mask_select_flush_all(Mask *mask)
{
	MaskLayer *masklay;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			int i;

			spline->flag &= ~SELECT;

			/* intentionally _dont_ do this in the masklay loop
			 * so we clear flags on all splines */
			if (masklay->restrictflag & MASK_RESTRICT_VIEW) {
				continue;
			}

			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *cur_point = &spline->points[i];

				if (MASKPOINT_ISSEL_ANY(cur_point)) {
					spline->flag |= SELECT;
				}
				else {
					int j;

					for (j = 0; j < cur_point->tot_uw; j++) {
						if (cur_point->uw[j].flag & SELECT) {
							spline->flag |= SELECT;
							break;
						}
					}
				}
			}
		}
	}
}
Esempio n. 10
0
static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *mask_layer = BKE_mask_layer_active(mask);
	MaskSpline *spline;

	if (mask_layer == NULL) {
		return OPERATOR_CANCELLED;
	}

	for (spline = mask_layer->splines.last;
	     spline;
	     spline = spline->prev)
	{
		MaskSplinePoint *point = spline->points;
		int i = 0;
		while (i < spline->tot_point) {
			int start = i, end = -1;
			/* Find next selected segment. */
			while (MASKPOINT_ISSEL_ANY(point)) {
				BKE_mask_point_select_set(point, false);
				end = i;
				if (i >= spline->tot_point - 1) {
					break;
				}
				i++;
				point++;
			}
			if (end >= start) {
				MaskSpline *new_spline = BKE_mask_spline_add(mask_layer);
				MaskSplinePoint *new_point;
				int b;

				/* BKE_mask_spline_add might allocate the points, need to free them in this case. */
				if (new_spline->points) {
					MEM_freeN(new_spline->points);
				}

				/* Copy options from old spline. */
				new_spline->flag = spline->flag;
				new_spline->offset_mode = spline->offset_mode;
				new_spline->weight_interp = spline->weight_interp;
				new_spline->parent = spline->parent;

				/* Allocate new points and copy them from old spline. */
				new_spline->tot_point = end - start + 1;
				new_spline->points = MEM_mallocN(sizeof(MaskSplinePoint) * new_spline->tot_point,
				                                 "duplicated mask points");

				memcpy(new_spline->points, spline->points + start,
				       new_spline->tot_point * sizeof(MaskSplinePoint));

				/* Select points and duplicate their UWs (if needed). */
				for (b = 0, new_point = new_spline->points;
				     b < new_spline->tot_point;
				     b++, new_point++)
				{
					if (new_point->uw) {
						new_point->uw = MEM_dupallocN(new_point->uw);
					}
					BKE_mask_point_select_set(new_point, true);
				}

				/* Clear cyclic flag if we didn't copy the whole spline. */
				if (new_spline->flag & MASK_SPLINE_CYCLIC) {
					if (start != 0 || end != spline->tot_point - 1) {
						new_spline->flag &= ~MASK_SPLINE_CYCLIC;
					}
				}

				/* Flush selection to splines. */
				new_spline->flag |= SELECT;
				spline->flag &= ~SELECT;

				mask_layer->act_spline = new_spline;
			}
			i++;
			point++;
		}
	}

	/* TODO: only update edited splines */
	BKE_mask_update_display(mask, CFRA);

	WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);

	return OPERATOR_FINISHED;
}
Esempio n. 11
0
static int add_vertex_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;

	float co[2];

	if (mask == NULL) {
		/* if there's no active mask, create one */
		mask = ED_mask_new(C, NULL);
	}

	masklay = BKE_mask_layer_active(mask);

	if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
		masklay = NULL;
	}

	RNA_float_get_array(op->ptr, "location", co);

	/* TODO, having an active point but no active spline is possible, why? */
	if (masklay && masklay->act_spline && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) {

		/* cheap trick - double click for cyclic */
		MaskSpline *spline = masklay->act_spline;
		MaskSplinePoint *point = masklay->act_point;

		const bool is_sta = (point == spline->points);
		const bool is_end = (point == &spline->points[spline->tot_point - 1]);

		/* then check are we overlapping the mouse */
		if ((is_sta || is_end) && equals_v2v2(co, point->bezt.vec[1])) {
			if (spline->flag & MASK_SPLINE_CYCLIC) {
				/* nothing to do */
				return OPERATOR_CANCELLED;
			}
			else {
				/* recalc the connecting point as well to make a nice even curve */
				MaskSplinePoint *point_other = is_end ? spline->points : &spline->points[spline->tot_point - 1];
				spline->flag |= MASK_SPLINE_CYCLIC;

				/* TODO, update keyframes in time */
				BKE_mask_calc_handle_point_auto(spline, point, false);
				BKE_mask_calc_handle_point_auto(spline, point_other, false);

				/* TODO: only update this spline */
				BKE_mask_update_display(mask, CFRA);

				WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
				return OPERATOR_FINISHED;
			}
		}

		if (!add_vertex_subdivide(C, mask, co)) {
			if (!add_vertex_extrude(C, mask, masklay, co)) {
				return OPERATOR_CANCELLED;
			}
		}
	}
	else {
		if (!add_vertex_subdivide(C, mask, co)) {
			if (!add_vertex_new(C, mask, masklay, co)) {
				return OPERATOR_CANCELLED;
			}
		}
	}

	/* TODO: only update this spline */
	BKE_mask_update_display(mask, CFRA);

	return OPERATOR_FINISHED;
}
Esempio n. 12
0
static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	const int frame = CFRA;
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	bool changed = false;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		if (masklay->splines_shapes.first) {
			MaskLayerShape *masklay_shape_reset;
			MaskLayerShape *masklay_shape;

			/* get the shapekey of the current state */
			masklay_shape_reset = BKE_mask_layer_shape_alloc(masklay, frame);
			/* initialize from mask - as if inseting a keyframe */
			BKE_mask_layer_shape_from_mask(masklay, masklay_shape_reset);

			for (masklay_shape = masklay->splines_shapes.first;
			     masklay_shape;
			     masklay_shape = masklay_shape->next)
			{

				if (masklay_shape_reset->tot_vert == masklay_shape->tot_vert) {
					int i_abs = 0;
					int i;
					MaskSpline *spline;
					MaskLayerShapeElem *shape_ele_src;
					MaskLayerShapeElem *shape_ele_dst;

					shape_ele_src = (MaskLayerShapeElem *)masklay_shape_reset->data;
					shape_ele_dst = (MaskLayerShapeElem *)masklay_shape->data;

					for (spline = masklay->splines.first; spline; spline = spline->next) {
						for (i = 0; i < spline->tot_point; i++) {
							MaskSplinePoint *point = &spline->points[i];

							if (MASKPOINT_ISSEL_ANY(point)) {
								/* TODO - nicer access here */
								shape_ele_dst->value[6] = shape_ele_src->value[6];
							}

							shape_ele_src++;
							shape_ele_dst++;

							i_abs++;
						}
					}

				}
				else {
					// printf("%s: skipping\n", __func__);
				}

				changed = true;
			}

			BKE_mask_layer_shape_free(masklay_shape_reset);
		}
	}

	if (changed) {
		WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
		DAG_id_tag_update(&mask->id, 0);

		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
Esempio n. 13
0
static int mask_select_more_less(bContext *C, bool more)
{
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			const bool cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0;
			bool start_sel, end_sel, prev_sel, cur_sel;
			int i;

			/* reselect point if any handle is selected to make the result more predictable */
			for (i = 0; i < spline->tot_point; i++) {
				BKE_mask_point_select_set(spline->points + i, MASKPOINT_ISSEL_ANY(spline->points + i));
			}

			/* select more/less does not affect empty/single point splines */
			if (spline->tot_point < 2) {
				continue;
			}

			if (cyclic) {
				start_sel = !!MASKPOINT_ISSEL_KNOT(spline->points);
				end_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[spline->tot_point - 1]);
			}
			else {
				start_sel = false;
				end_sel = false;
			}

			for (i = 0; i < spline->tot_point; i++) {
				if (i == 0 && !cyclic) {
					continue;
				}

				prev_sel = (i > 0) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i - 1]) : end_sel;
				cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]);

				if (cur_sel != more) {
					if (prev_sel == more) {
						BKE_mask_point_select_set(&spline->points[i], more);
					}
					i++;
				}
			}

			for (i = spline->tot_point - 1; i >= 0; i--) {
				if (i == spline->tot_point - 1 && !cyclic) {
					continue;
				}

				prev_sel = (i < spline->tot_point - 1) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i + 1]) : start_sel;
				cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]);

				if (cur_sel != more) {
					if (prev_sel == more) {
						BKE_mask_point_select_set(&spline->points[i], more);
					}
					i--;
				}
			}
		}
	}

	WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);

	return OPERATOR_FINISHED;
}
Esempio n. 14
0
static int select_exec(bContext *C, wmOperator *op)
{
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	MaskSpline *spline;
	MaskSplinePoint *point = NULL;
	float co[2];
	bool extend = RNA_boolean_get(op->ptr, "extend");
	bool deselect = RNA_boolean_get(op->ptr, "deselect");
	bool toggle = RNA_boolean_get(op->ptr, "toggle");
	eMaskWhichHandle which_handle;
	const float threshold = 19;

	RNA_float_get_array(op->ptr, "location", co);

	point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &which_handle, NULL);

	if (extend == false && deselect == false && toggle == false)
		ED_mask_select_toggle_all(mask, SEL_DESELECT);

	if (point) {
		if (which_handle != MASK_WHICH_HANDLE_NONE) {
			if (extend) {
				masklay->act_spline = spline;
				masklay->act_point = point;

				BKE_mask_point_select_set_handle(point, which_handle, true);
			}
			else if (deselect) {
				BKE_mask_point_select_set_handle(point, which_handle, false);
			}
			else {
				masklay->act_spline = spline;
				masklay->act_point = point;

				if (!MASKPOINT_ISSEL_HANDLE(point, which_handle)) {
					BKE_mask_point_select_set_handle(point, which_handle, true);
				}
				else if (toggle) {
					BKE_mask_point_select_set_handle(point, which_handle, false);
				}
			}
		}
		else {
			if (extend) {
				masklay->act_spline = spline;
				masklay->act_point = point;

				BKE_mask_point_select_set(point, true);
			}
			else if (deselect) {
				BKE_mask_point_select_set(point, false);
			}
			else {
				masklay->act_spline = spline;
				masklay->act_point = point;

				if (!MASKPOINT_ISSEL_ANY(point)) {
					BKE_mask_point_select_set(point, true);
				}
				else if (toggle) {
					BKE_mask_point_select_set(point, false);
				}
			}
		}

		masklay->act_spline = spline;
		masklay->act_point = point;

		ED_mask_select_flush_all(mask);

		WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);

		return OPERATOR_FINISHED;
	}
	else {
		MaskSplinePointUW *uw;

		if (ED_mask_feather_find_nearest(C, mask, co, threshold, &masklay, &spline, &point, &uw, NULL)) {

			if (extend) {
				masklay->act_spline = spline;
				masklay->act_point = point;

				if (uw) uw->flag |= SELECT;
			}
			else if (deselect) {
				if (uw) uw->flag &= ~SELECT;
			}
			else {
				masklay->act_spline = spline;
				masklay->act_point = point;

				if (uw) {
					if (!(uw->flag & SELECT)) {
						uw->flag |= SELECT;
					}
					else if (toggle) {
						uw->flag &= ~SELECT;
					}
				}
			}

			ED_mask_select_flush_all(mask);

			WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);

			return OPERATOR_FINISHED;
		}
	}

	return OPERATOR_PASS_THROUGH;
}
Esempio n. 15
0
/*
 * - loop over selected shapekeys.
 * - find firstsel/lastsel pairs.
 * - move these into a temp list.
 * - re-key all the original shapes.
 * - copy unselected values back from the original.
 * - free the original.
 */
static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	const int frame = CFRA;
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	bool changed = false;

	const bool do_feather  = RNA_boolean_get(op->ptr, "feather");
	const bool do_location = RNA_boolean_get(op->ptr, "location");

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		/* we need at least one point selected here to bother re-interpolating */
		if (!ED_mask_layer_select_check(masklay)) {
			continue;
		}

		if (masklay->splines_shapes.first) {
			MaskLayerShape *masklay_shape, *masklay_shape_next;
			MaskLayerShape *masklay_shape_lastsel = NULL;

			for (masklay_shape = masklay->splines_shapes.first;
			     masklay_shape;
			     masklay_shape = masklay_shape_next)
			{
				MaskLayerShape *masklay_shape_a = NULL;
				MaskLayerShape *masklay_shape_b = NULL;

				masklay_shape_next = masklay_shape->next;

				/* find contiguous selections */
				if (masklay_shape->flag & MASK_SHAPE_SELECT) {
					if (masklay_shape_lastsel == NULL) {
						masklay_shape_lastsel = masklay_shape;
					}
					if ((masklay_shape->next == NULL) ||
					    (((MaskLayerShape *)masklay_shape->next)->flag & MASK_SHAPE_SELECT) == 0)
					{
						masklay_shape_a = masklay_shape_lastsel;
						masklay_shape_b = masklay_shape;
						masklay_shape_lastsel = NULL;

						/* this will be freed below, step over selection */
						masklay_shape_next = masklay_shape->next;
					}
				}

				/* we have a from<>to? - re-interpolate! */
				if (masklay_shape_a && masklay_shape_b) {
					ListBase shapes_tmp = {NULL, NULL};
					MaskLayerShape *masklay_shape_tmp;
					MaskLayerShape *masklay_shape_tmp_next;
					MaskLayerShape *masklay_shape_tmp_last = masklay_shape_b->next;
					MaskLayerShape *masklay_shape_tmp_rekey;

					/* move keys */
					for (masklay_shape_tmp = masklay_shape_a;
					     masklay_shape_tmp && (masklay_shape_tmp != masklay_shape_tmp_last);
					     masklay_shape_tmp = masklay_shape_tmp_next)
					{
						masklay_shape_tmp_next = masklay_shape_tmp->next;
						BLI_remlink(&masklay->splines_shapes, masklay_shape_tmp);
						BLI_addtail(&shapes_tmp, masklay_shape_tmp);
					}

					/* re-key, note: cant modify the keys here since it messes uop */
					for (masklay_shape_tmp = shapes_tmp.first;
					     masklay_shape_tmp;
					     masklay_shape_tmp = masklay_shape_tmp->next)
					{
						BKE_mask_layer_evaluate(masklay, masklay_shape_tmp->frame, true);
						masklay_shape_tmp_rekey = BKE_mask_layer_shape_verify_frame(masklay, masklay_shape_tmp->frame);
						BKE_mask_layer_shape_from_mask(masklay, masklay_shape_tmp_rekey);
						masklay_shape_tmp_rekey->flag = masklay_shape_tmp->flag & MASK_SHAPE_SELECT;
					}

					/* restore unselected points and free copies */
					for (masklay_shape_tmp = shapes_tmp.first;
					     masklay_shape_tmp;
					     masklay_shape_tmp = masklay_shape_tmp_next)
					{
						/* restore */
						int i_abs = 0;
						int i;
						MaskSpline *spline;
						MaskLayerShapeElem *shape_ele_src;
						MaskLayerShapeElem *shape_ele_dst;

						masklay_shape_tmp_next = masklay_shape_tmp->next;

						/* we know this exists, added above */
						masklay_shape_tmp_rekey = BKE_mask_layer_shape_find_frame(masklay, masklay_shape_tmp->frame);

						shape_ele_src = (MaskLayerShapeElem *)masklay_shape_tmp->data;
						shape_ele_dst = (MaskLayerShapeElem *)masklay_shape_tmp_rekey->data;

						for (spline = masklay->splines.first; spline; spline = spline->next) {
							for (i = 0; i < spline->tot_point; i++) {
								MaskSplinePoint *point = &spline->points[i];

								/* not especially efficient but makes this easier to follow */
								SWAP(MaskLayerShapeElem, *shape_ele_src, *shape_ele_dst);

								if (MASKPOINT_ISSEL_ANY(point)) {
									if (do_location) {
										memcpy(shape_ele_dst->value, shape_ele_src->value, sizeof(float) * 6);
									}
									if (do_feather) {
										shape_ele_dst->value[6] = shape_ele_src->value[6];
									}
								}

								shape_ele_src++;
								shape_ele_dst++;

								i_abs++;
							}
						}

						BKE_mask_layer_shape_free(masklay_shape_tmp);
					}

					changed = true;
				}
			}

			/* re-evaluate */
			BKE_mask_layer_evaluate(masklay, frame, true);
		}
	}

	if (changed) {
		WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
		DAG_id_tag_update(&mask->id, 0);

		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
Esempio n. 16
0
static int delete_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	bool changed = false;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;
		int mask_layer_shape_ofs = 0;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		spline = masklay->splines.first;

		while (spline) {
			const int tot_point_orig = spline->tot_point;
			int i, count = 0;
			MaskSpline *next_spline = spline->next;

			/* count unselected points */
			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *point = &spline->points[i];

				if (!MASKPOINT_ISSEL_ANY(point))
					count++;
			}

			if (count == 0) {
				/* delete the whole spline */
				BLI_remlink(&masklay->splines, spline);
				BKE_mask_spline_free(spline);

				if (spline == masklay->act_spline) {
					masklay->act_spline = NULL;
					masklay->act_point = NULL;
				}

				BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs, tot_point_orig);
			}
			else {
				MaskSplinePoint *new_points;
				int j;

				new_points = MEM_callocN(count * sizeof(MaskSplinePoint), "deleteMaskPoints");

				for (i = 0, j = 0; i < tot_point_orig; i++) {
					MaskSplinePoint *point = &spline->points[i];

					if (!MASKPOINT_ISSEL_ANY(point)) {
						if (point == masklay->act_point)
							masklay->act_point = &new_points[j];

						delete_feather_points(point);

						new_points[j] = *point;
						j++;
					}
					else {
						if (point == masklay->act_point)
							masklay->act_point = NULL;

						BKE_mask_point_free(point);
						spline->tot_point--;

						BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs + j, 1);
					}
				}

				mask_layer_shape_ofs += spline->tot_point;

				MEM_freeN(spline->points);
				spline->points = new_points;

				ED_mask_select_flush_all(mask);
			}

			changed = true;
			spline = next_spline;
		}

		/* not essential but confuses users when there are keys with no data!
		 * assume if they delete all data from the layer they also dont care about keys */
		if (masklay->splines.first == NULL) {
			BKE_mask_layer_free_shapes(masklay);
		}
	}

	if (!changed) {
		return OPERATOR_CANCELLED;
	}

	/* TODO: only update edited splines */
	BKE_mask_update_display(mask, CFRA);

	WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);

	return OPERATOR_FINISHED;
}
Esempio n. 17
0
/* return non-zero if spline is selected */
static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline,
                               const char draw_flag, const char draw_type,
                               const float xscale, const float yscale)
{
	const bool is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0;
	const bool is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH) != 0;

	unsigned char rgb_spline[4];
	MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
	SpaceClip *sc = CTX_wm_space_clip(C);
	bool undistort = false;

	int i, handle_size, tot_feather_point;
	float (*feather_points)[2], (*fp)[2];
	float min[2], max[2];

	if (!spline->tot_point)
		return;

	if (sc)
		undistort = sc->clip && (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT);

	/* TODO, add this to sequence editor */
	handle_size = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize;

	glPointSize(handle_size);

	mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline);

	/* feather points */
	feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point);
	for (i = 0; i < spline->tot_point; i++) {

		/* watch it! this is intentionally not the deform array, only check for sel */
		MaskSplinePoint *point = &spline->points[i];

		int j;

		for (j = 0; j <= point->tot_uw; j++) {
			float feather_point[2];
			bool sel = false;

			copy_v2_v2(feather_point, *fp);

			if (undistort)
				mask_point_undistort_pos(sc, feather_point, feather_point);

			if (j == 0) {
				sel = MASKPOINT_ISSEL_ANY(point);
			}
			else {
				sel = (point->uw[j - 1].flag & SELECT) != 0;
			}

			if (sel) {
				if (point == masklay->act_point)
					glColor3f(1.0f, 1.0f, 1.0f);
				else
					UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
			}
			else {
				UI_ThemeColor(TH_HANDLE_VERTEX);
			}

			glBegin(GL_POINTS);
			glVertex2fv(feather_point);
			glEnd();

			fp++;
		}
	}
	MEM_freeN(feather_points);

	if (is_smooth) {
		glEnable(GL_LINE_SMOOTH);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

	/* control points */
	INIT_MINMAX2(min, max);
	for (i = 0; i < spline->tot_point; i++) {

		/* watch it! this is intentionally not the deform array, only check for sel */
		MaskSplinePoint *point = &spline->points[i];
		MaskSplinePoint *point_deform = &points_array[i];
		BezTriple *bezt = &point_deform->bezt;

		float vert[2];

		copy_v2_v2(vert, bezt->vec[1]);

		if (undistort) {
			mask_point_undistort_pos(sc, vert, vert);
		}

		/* draw handle segment */
		if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
			float handle[2];
			BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_STICK, handle);
			if (undistort) {
				mask_point_undistort_pos(sc, handle, handle);
			}
			draw_single_handle(masklay, point, MASK_WHICH_HANDLE_STICK,
			                   draw_type, handle_size, xscale, yscale, vert, handle);
		}
		else {
			float handle_left[2], handle_right[2];
			BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_LEFT, handle_left);
			BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_RIGHT, handle_right);
			if (undistort) {
				mask_point_undistort_pos(sc, handle_left, handle_left);
				mask_point_undistort_pos(sc, handle_left, handle_left);
			}
			draw_single_handle(masklay, point, MASK_WHICH_HANDLE_LEFT,
			                   draw_type, handle_size, xscale, yscale, vert, handle_left);
			draw_single_handle(masklay, point, MASK_WHICH_HANDLE_RIGHT,
			                   draw_type, handle_size, xscale, yscale, vert, handle_right);
		}

		/* draw CV point */
		if (MASKPOINT_ISSEL_KNOT(point)) {
			if (point == masklay->act_point)
				glColor3f(1.0f, 1.0f, 1.0f);
			else
				UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
		}
		else
			UI_ThemeColor(TH_HANDLE_VERTEX);

		glBegin(GL_POINTS);
		glVertex2fv(vert);
		glEnd();

		minmax_v2v2_v2(min, max, vert);
	}

	if (is_spline_sel) {
		float x = (min[0] + max[0]) / 2.0f;
		float y = (min[1] + max[1]) / 2.0f;
		/* TODO(sergey): Remove hardcoded colors. */
		if (masklay->act_spline == spline) {
			glColor3ub(255, 255, 255);
		}
		else {
			glColor3ub(255, 255, 0);
		}

		draw_circle(x, y, 6.0f, true, xscale, yscale);

		glColor3ub(0, 0, 0);
		draw_circle(x, y, 6.0f, false, xscale, yscale);
	}

	if (is_smooth) {
		glDisable(GL_LINE_SMOOTH);
		glDisable(GL_BLEND);
	}
}
Esempio n. 18
0
static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
{
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;

	/* parent info */
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking;
	MovieTrackingTrack *track;
	MovieTrackingPlaneTrack *plane_track;
	MovieTrackingObject *tracking_object;
	/* done */

	int framenr, parent_type;
	float parmask_pos[2], orig_corners[4][2];
	char *sub_parent_name;

	if (ELEM(NULL, sc, clip)) {
		return OPERATOR_CANCELLED;
	}

	framenr = ED_space_clip_get_clip_frame_number(sc);

	tracking = &clip->tracking;
	tracking_object = BKE_tracking_object_get_active(&clip->tracking);

	if (tracking_object == NULL) {
		return OPERATOR_CANCELLED;
	}

	if ((track = BKE_tracking_track_get_active(tracking)) != NULL) {
		MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
		float marker_pos_ofs[2];

		add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);

		BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs);

		sub_parent_name = track->name;
		parent_type = MASK_PARENT_POINT_TRACK;
		memset(orig_corners, 0, sizeof(orig_corners));
	}
	else if ((plane_track = BKE_tracking_plane_track_get_active(tracking)) != NULL) {
		MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);

		zero_v2(parmask_pos);
		sub_parent_name = plane_track->name;
		parent_type = MASK_PARENT_PLANE_TRACK;
		memcpy(orig_corners, plane_marker->corners, sizeof(orig_corners));
	}
	else {
		return OPERATOR_CANCELLED;
	}

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;
		int i;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *point = &spline->points[i];

				if (MASKPOINT_ISSEL_ANY(point)) {
					point->parent.id_type = ID_MC;
					point->parent.id = &clip->id;
					point->parent.type = parent_type;
					BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent));
					BLI_strncpy(point->parent.sub_parent, sub_parent_name, sizeof(point->parent.sub_parent));

					copy_v2_v2(point->parent.parent_orig, parmask_pos);
					memcpy(point->parent.parent_corners_orig, orig_corners, sizeof(point->parent.parent_corners_orig));
				}
			}
		}
	}

	WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
	DAG_id_tag_update(&mask->id, 0);

	return OPERATOR_FINISHED;
}
Esempio n. 19
0
/* return non-zero if spline is selected */
static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline,
                               const char UNUSED(draw_flag), const char draw_type)
{
	const bool is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0;
	unsigned char rgb_spline[4];
	MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
	SpaceClip *sc = CTX_wm_space_clip(C);
	int undistort = FALSE;

	int i, hsize, tot_feather_point;
	float (*feather_points)[2], (*fp)[2];

	if (!spline->tot_point)
		return;

	if (sc)
		undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;

	/* TODO, add this to sequence editor */
	hsize = 4; /* UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); */

	glPointSize(hsize);

	mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline);

	/* feather points */
	feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point);
	for (i = 0; i < spline->tot_point; i++) {

		/* watch it! this is intentionally not the deform array, only check for sel */
		MaskSplinePoint *point = &spline->points[i];

		int j;

		for (j = 0; j <= point->tot_uw; j++) {
			float feather_point[2];
			int sel = FALSE;

			copy_v2_v2(feather_point, *fp);

			if (undistort)
				mask_point_undistort_pos(sc, feather_point, feather_point);

			if (j == 0) {
				sel = MASKPOINT_ISSEL_ANY(point);
			}
			else {
				sel = point->uw[j - 1].flag & SELECT;
			}

			if (sel) {
				if (point == masklay->act_point)
					glColor3f(1.0f, 1.0f, 1.0f);
				else
					glColor3f(1.0f, 1.0f, 0.0f);
			}
			else {
				glColor3f(0.5f, 0.5f, 0.0f);
			}

			glBegin(GL_POINTS);
			glVertex2fv(feather_point);
			glEnd();

			fp++;
		}
	}
	MEM_freeN(feather_points);

	/* control points */
	for (i = 0; i < spline->tot_point; i++) {

		/* watch it! this is intentionally not the deform array, only check for sel */
		MaskSplinePoint *point = &spline->points[i];
		MaskSplinePoint *point_deform = &points_array[i];
		BezTriple *bezt = &point_deform->bezt;

		float handle[2];
		float vert[2];
		const bool has_handle = BKE_mask_point_has_handle(point);

		copy_v2_v2(vert, bezt->vec[1]);
		BKE_mask_point_handle(point_deform, handle);

		if (undistort) {
			mask_point_undistort_pos(sc, vert, vert);
			mask_point_undistort_pos(sc, handle, handle);
		}

		/* draw handle segment */
		if (has_handle) {

			/* this could be split into its own loop */
			if (draw_type == MASK_DT_OUTLINE) {
				const unsigned char rgb_gray[4] = {0x60, 0x60, 0x60, 0xff};
				glLineWidth(3);
				glColor4ubv(rgb_gray);
				glBegin(GL_LINES);
				glVertex2fv(vert);
				glVertex2fv(handle);
				glEnd();
				glLineWidth(1);
			}

			glColor3ubv(rgb_spline);
			glBegin(GL_LINES);
			glVertex2fv(vert);
			glVertex2fv(handle);
			glEnd();
		}

		/* draw CV point */
		if (MASKPOINT_ISSEL_KNOT(point)) {
			if (point == masklay->act_point)
				glColor3f(1.0f, 1.0f, 1.0f);
			else
				glColor3f(1.0f, 1.0f, 0.0f);
		}
		else
			glColor3f(0.5f, 0.5f, 0.0f);

		glBegin(GL_POINTS);
		glVertex2fv(vert);
		glEnd();

		/* draw handle points */
		if (has_handle) {
			if (MASKPOINT_ISSEL_HANDLE(point)) {
				if (point == masklay->act_point)
					glColor3f(1.0f, 1.0f, 1.0f);
				else
					glColor3f(1.0f, 1.0f, 0.0f);
			}
			else {
				glColor3f(0.5f, 0.5f, 0.0f);
			}

			glBegin(GL_POINTS);
			glVertex2fv(handle);
			glEnd();
		}
	}

	glPointSize(1.0f);
}