示例#1
0
static int create_primitive_from_points(bContext *C, wmOperator *op, const float (*points)[2],
                                        int num_points, char handle_type)
{
	ScrArea *sa = CTX_wm_area(C);
	Scene *scene = CTX_data_scene(C);
	Mask *mask;
	MaskLayer *mask_layer;
	MaskSpline *new_spline;
	float scale, location[2], frame_size[2];
	int i, width, height;
	int size = RNA_float_get(op->ptr, "size");

	ED_mask_get_size(sa, &width, &height);
	scale = (float)size / max_ii(width, height);

	/* Get location in mask space. */
	frame_size[0] = width;
	frame_size[1] = height;
	RNA_float_get_array(op->ptr, "location", location);
	location[0] /= width;
	location[1] /= height;
	BKE_mask_coord_from_frame(location, location, frame_size);

	/* Make it so new primitive is centered to mouse location. */
	location[0] -= 0.5f * scale;
	location[1] -= 0.5f * scale;

	mask_layer = ED_mask_layer_ensure(C);
	mask = CTX_data_edit_mask(C);

	ED_mask_select_toggle_all(mask, SEL_DESELECT);

	new_spline = BKE_mask_spline_add(mask_layer);
	new_spline->flag = MASK_SPLINE_CYCLIC | SELECT;
	new_spline->tot_point = num_points;
	new_spline->points = MEM_recallocN(new_spline->points,
	                                   sizeof(MaskSplinePoint) * new_spline->tot_point);

	mask_layer->act_spline = new_spline;
	mask_layer->act_point = NULL;

	for (i = 0; i < num_points; i++) {
		MaskSplinePoint *new_point = &new_spline->points[i];

		copy_v2_v2(new_point->bezt.vec[1], points[i]);
		mul_v2_fl(new_point->bezt.vec[1], scale);
		add_v2_v2(new_point->bezt.vec[1], location);

		new_point->bezt.h1 = handle_type;
		new_point->bezt.h2 = handle_type;
		BKE_mask_point_select_set(new_point, true);
	}

	WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);

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

	return OPERATOR_FINISHED;
}
示例#2
0
void ED_mask_draw(const bContext *C,
                  const char draw_flag, const char draw_type)
{
	ScrArea *sa = CTX_wm_area(C);

	Mask *mask = CTX_data_edit_mask(C);
	int width, height;

	if (!mask)
		return;

	ED_mask_get_size(sa, &width, &height);

	draw_masklays(C, mask, draw_flag, draw_type, width, height);
}
示例#3
0
static int primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
	ScrArea *sa = CTX_wm_area(C);
	float cursor[2];
	int width, height;

	ED_mask_get_size(sa, &width, &height);
	ED_mask_cursor_location_get(sa, cursor);

	cursor[0] *= width;
	cursor[1] *= height;

	RNA_float_set_array(op->ptr, "location", cursor);

	return op->type->exec(C, op);
}
示例#4
0
void ED_mask_draw(const bContext *C,
                  const char draw_flag, const char draw_type)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);

	Mask *mask = CTX_data_edit_mask(C);
	int width, height;
	float aspx, aspy;
	float xscale, yscale;

	if (!mask)
		return;

	ED_mask_get_size(sa, &width, &height);
	ED_mask_get_aspect(sa, ar, &aspx, &aspy);
	UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);

	draw_masklays(C, mask, draw_flag, draw_type, width, height, xscale * aspx, yscale * aspy);
}
示例#5
0
MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, Mask *mask, const float normal_co[2], const float threshold,
                                            MaskLayer **masklay_r, MaskSpline **spline_r, bool *is_handle_r,
                                            float *score)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);

	MaskLayer *masklay;
	MaskLayer *point_masklay = NULL;
	MaskSpline *point_spline = NULL;
	MaskSplinePoint *point = NULL;
	float co[2];
	const float threshold_sq = threshold * threshold;
	float len_sq = FLT_MAX, scalex, scaley;
	int is_handle = FALSE, width, height;

	ED_mask_get_size(sa, &width, &height);
	ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);

	co[0] = normal_co[0] * scalex;
	co[1] = normal_co[1] * scaley;

	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) {
			MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);

			int i;

			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *cur_point = &spline->points[i];
				MaskSplinePoint *cur_point_deform = &points_array[i];
				float cur_len_sq, vec[2], handle[2];

				vec[0] = cur_point_deform->bezt.vec[1][0] * scalex;
				vec[1] = cur_point_deform->bezt.vec[1][1] * scaley;

				if (BKE_mask_point_has_handle(cur_point)) {
					BKE_mask_point_handle(cur_point_deform, handle);
					handle[0] *= scalex;
					handle[1] *= scaley;

					cur_len_sq = len_squared_v2v2(co, handle);

					if (cur_len_sq < len_sq) {
						point_masklay = masklay;
						point_spline = spline;
						point = cur_point;
						len_sq = cur_len_sq;
						is_handle = TRUE;
					}
				}

				cur_len_sq = len_squared_v2v2(co, vec);

				if (cur_len_sq < len_sq) {
					point_spline = spline;
					point_masklay = masklay;
					point = cur_point;
					len_sq = cur_len_sq;
					is_handle = FALSE;
				}
			}
		}
	}

	if (len_sq < threshold_sq) {
		if (masklay_r)
			*masklay_r = point_masklay;

		if (spline_r)
			*spline_r = point_spline;

		if (is_handle_r)
			*is_handle_r = is_handle;

		if (score)
			*score = sqrtf(len_sq);

		return point;
	}

	if (masklay_r)
		*masklay_r = NULL;

	if (spline_r)
		*spline_r = NULL;

	if (is_handle_r)
		*is_handle_r = FALSE;

	return NULL;
}
示例#6
0
static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *event)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);

	Mask *mask = CTX_data_edit_mask(C);
	SlidePointData *customdata = NULL;
	MaskLayer *masklay, *cv_masklay, *feather_masklay;
	MaskSpline *spline, *cv_spline, *feather_spline;
	MaskSplinePoint *point, *cv_point, *feather_point;
	MaskSplinePointUW *uw = NULL;
	int width, height, action = SLIDE_ACTION_NONE;
	bool is_handle = false;
	const bool slide_feather = RNA_boolean_get(op->ptr, "slide_feather");
	float co[2], cv_score, feather_score;
	const float threshold = 19;

	ED_mask_mouse_pos(sa, ar, event->mval, co);
	ED_mask_get_size(sa, &width, &height);

	cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_masklay, &cv_spline, &is_handle, &cv_score);

	if (ED_mask_feather_find_nearest(C, mask, co, threshold, &feather_masklay, &feather_spline, &feather_point, &uw, &feather_score)) {
		if (slide_feather || !cv_point || feather_score < cv_score) {
			action = SLIDE_ACTION_FEATHER;

			masklay = feather_masklay;
			spline = feather_spline;
			point = feather_point;
		}
	}

	if (cv_point && action == SLIDE_ACTION_NONE) {
		if (is_handle)
			action = SLIDE_ACTION_HANDLE;
		else
			action = SLIDE_ACTION_POINT;

		masklay = cv_masklay;
		spline = cv_spline;
		point = cv_point;
	}

	if (action != SLIDE_ACTION_NONE) {
		customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data");

		customdata->mask = mask;
		customdata->masklay = masklay;
		customdata->spline = spline;
		customdata->point = point;
		customdata->width = width;
		customdata->height = height;
		customdata->action = action;
		customdata->uw = uw;

		if (uw) {
			float co_uw[2];
			float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u);

			customdata->weight = uw->w;
			customdata->weight_scalar = weight_scalar;
			BKE_mask_point_segment_co(spline, point, uw->u, co_uw);
			BKE_mask_point_normal(spline, point, uw->u, customdata->no);

			madd_v2_v2v2fl(customdata->feather, co_uw, customdata->no, uw->w * weight_scalar);
		}
		else {
			BezTriple *bezt = &point->bezt;

			customdata->weight = bezt->weight;
			customdata->weight_scalar = 1.0f;
			BKE_mask_point_normal(spline, point, 0.0f, customdata->no);

			madd_v2_v2v2fl(customdata->feather, bezt->vec[1], customdata->no, bezt->weight);
		}

		if (customdata->action == SLIDE_ACTION_FEATHER)
			customdata->initial_feather = slide_point_check_initial_feather(spline);

		copy_m3_m3(customdata->vec, point->bezt.vec);
		if (BKE_mask_point_has_handle(point))
			BKE_mask_point_handle(point, customdata->handle);
		ED_mask_mouse_pos(sa, ar, event->mval, customdata->co);
	}

	return customdata;
}
示例#7
0
bool ED_mask_feather_find_nearest(const bContext *C, Mask *mask, const float normal_co[2], const float threshold,
                                  MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r,
                                  MaskSplinePointUW **uw_r, float *score)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);

	MaskLayer *masklay, *point_masklay = NULL;
	MaskSpline *point_spline = NULL;
	MaskSplinePoint *point = NULL;
	MaskSplinePointUW *uw = NULL;
	const float threshold_sq = threshold * threshold;
	float len = FLT_MAX, co[2];
	float scalex, scaley;
	int width, height;

	ED_mask_get_size(sa, &width, &height);
	ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);

	co[0] = normal_co[0] * scalex;
	co[1] = normal_co[1] * scaley;

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

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			//MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);

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

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

			feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point);

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

				for (j = 0; j <= cur_point->tot_uw; j++) {
					float cur_len_sq, vec[2];

					vec[0] = (*fp)[0] * scalex;
					vec[1] = (*fp)[1] * scaley;

					cur_len_sq = len_squared_v2v2(vec, co);

					if (point == NULL || cur_len_sq < len) {
						if (j == 0)
							uw = NULL;
						else
							uw = &cur_point->uw[j - 1];

						point_masklay = masklay;
						point_spline = spline;
						point = cur_point;
						len = cur_len_sq;
					}

					fp++;
				}
			}

			MEM_freeN(feather_points);
		}
	}

	if (len < threshold_sq) {
		if (masklay_r)
			*masklay_r = point_masklay;

		if (spline_r)
			*spline_r = point_spline;

		if (point_r)
			*point_r = point;

		if (uw_r)
			*uw_r = uw;

		if (score)
			*score = sqrtf(len);

		return TRUE;
	}

	if (masklay_r)
		*masklay_r = NULL;

	if (spline_r)
		*spline_r = NULL;

	if (point_r)
		*point_r = NULL;

	return FALSE;
}
示例#8
0
bool ED_mask_find_nearest_diff_point(const bContext *C,
                                     struct Mask *mask,
                                     const float normal_co[2],
                                     int threshold, bool feather,
                                     MaskLayer **masklay_r,
                                     MaskSpline **spline_r,
                                     MaskSplinePoint **point_r,
                                     float *u_r, float tangent[2],
                                     const bool use_deform,
                                     const bool use_project)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);

	MaskLayer *masklay, *point_masklay;
	MaskSpline *point_spline;
	MaskSplinePoint *point = NULL;
	float dist = FLT_MAX, co[2];
	int width, height;
	float u;
	float scalex, scaley;

	ED_mask_get_size(sa, &width, &height);
	ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);

	co[0] = normal_co[0] * scalex;
	co[1] = normal_co[1] * scaley;

	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) {
			int i;
			MaskSplinePoint *cur_point;

			for (i = 0, cur_point = use_deform ? spline->points_deform : spline->points;
			     i < spline->tot_point;
			     i++, cur_point++)
			{
				float *diff_points;
				unsigned int tot_diff_point;

				diff_points = BKE_mask_point_segment_diff(spline, cur_point, width, height,
				                                          &tot_diff_point);

				if (diff_points) {
					int j, tot_point;
					unsigned int tot_feather_point;
					float *feather_points = NULL, *points;

					if (feather) {
						feather_points = BKE_mask_point_segment_feather_diff(spline, cur_point,
						                                                     width, height,
						                                                     &tot_feather_point);

						points = feather_points;
						tot_point = tot_feather_point;
					}
					else {
						points = diff_points;
						tot_point = tot_diff_point;
					}

					for (j = 0; j < tot_point - 1; j++) {
						float cur_dist, a[2], b[2];

						a[0] = points[2 * j] * scalex;
						a[1] = points[2 * j + 1] * scaley;

						b[0] = points[2 * j + 2] * scalex;
						b[1] = points[2 * j + 3] * scaley;

						cur_dist = dist_to_line_segment_v2(co, a, b);

						if (cur_dist < dist) {
							if (tangent)
								sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]);

							point_masklay = masklay;
							point_spline = spline;
							point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point;
							dist = cur_dist;
							u = (float)j / tot_point;
						}
					}

					if (feather_points)
						MEM_freeN(feather_points);

					MEM_freeN(diff_points);
				}
			}
		}
	}

	if (point && dist < threshold) {
		if (masklay_r)
			*masklay_r = point_masklay;

		if (spline_r)
			*spline_r = point_spline;

		if (point_r)
			*point_r = point;

		if (u_r) {
			/* TODO(sergey): Projection fails in some weirdo cases.. */
			if (use_project) {
				u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY);
			}

			*u_r = u;
		}

		return true;
	}

	if (masklay_r)
		*masklay_r = NULL;

	if (spline_r)
		*spline_r = NULL;

	if (point_r)
		*point_r = NULL;

	return false;
}
示例#9
0
static int circle_select_exec(bContext *C, wmOperator *op)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);

	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	int i;

	float zoomx, zoomy, offset[2], ellipse[2];
	int width, height;
	bool changed = false;

	/* get operator properties */
	const int x = RNA_int_get(op->ptr, "x");
	const int y = RNA_int_get(op->ptr, "y");
	const int radius = RNA_int_get(op->ptr, "radius");

	const bool select = !RNA_boolean_get(op->ptr, "deselect");

	/* compute ellipse and position in unified coordinates */
	ED_mask_get_size(sa, &width, &height);
	ED_mask_zoom(sa, ar, &zoomx, &zoomy);
	width = height = max_ii(width, height);

	ellipse[0] = width * zoomx / radius;
	ellipse[1] = height * zoomy / radius;

	ED_mask_point_pos(sa, ar, x, y, &offset[0], &offset[1]);

	/* do actual selection */
	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) {
			MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);

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

				if (mask_spline_point_inside_ellipse(&point_deform->bezt, offset, ellipse)) {
					BKE_mask_point_select_set(point, select);
					BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, select);

					changed = true;
				}
			}
		}
	}

	if (changed) {
		ED_mask_select_flush_all(mask);

		WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);

		return OPERATOR_FINISHED;
	}

	return OPERATOR_CANCELLED;
}