static MovieTrackingPlaneTrack *find_nearest_plane_track(SpaceClip *sc, ListBase *plane_tracks_base,
                                                         float co[2], float *distance_r)
{
	MovieTrackingPlaneTrack *plane_track = NULL, *current_plane_track;
	float min_distance = 0.0f;
	int framenr = ED_space_clip_get_clip_frame_number(sc);

	for (current_plane_track = plane_tracks_base->first;
	     current_plane_track;
	     current_plane_track = current_plane_track->next)
	{
		MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(current_plane_track, framenr);

		if ((current_plane_track->flag & TRACK_HIDDEN) == 0) {
			float distance = dist_to_crns_abs(co, plane_marker->corners);
			if (plane_track == NULL || distance < min_distance) {
				plane_track = current_plane_track;
				min_distance = distance;
			}
		}
	}

	*distance_r = min_distance;

	return plane_track;
}
void PlaneTrackCommonOperation::initExecution()
{
	MovieTracking *tracking;
	MovieTrackingObject *object;

	memset(this->m_corners, 0, sizeof(this->m_corners));
	memset(this->m_frameSpaceCorners, 0, sizeof(this->m_frameSpaceCorners));

	if (!this->m_movieClip)
		return;

	tracking = &this->m_movieClip->tracking;

	object = BKE_tracking_object_get_named(tracking, this->m_trackingObjectName);
	if (object) {
		MovieTrackingPlaneTrack *plane_track;

		plane_track = BKE_tracking_plane_track_get_named(tracking, object, this->m_planeTrackName);

		if (plane_track) {
			MovieTrackingPlaneMarker *plane_marker;
			int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);

			plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr);
			memcpy(this->m_corners, plane_marker->corners, sizeof(this->m_corners));
		}
	}

	for (int i = 0; i < 4; i++) {
		this->m_frameSpaceCorners[i][0] = this->m_corners[i][0] * this->getWidth();
		this->m_frameSpaceCorners[i][1] = this->m_corners[i][1] * this->getHeight();
	}
}
static MovieTrackingPlaneTrack *tracking_plane_marker_check_slide(
        bContext *C,
        const wmEvent *event,
        int *corner_r)
{
	const float distance_clip_squared = 12.0f * 12.0f;
	SpaceClip *sc = CTX_wm_space_clip(C);
	ARegion *ar = CTX_wm_region(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	int width, height;
	float co[2];
	ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
	int framenr = ED_space_clip_get_clip_frame_number(sc);

	ED_space_clip_get_size(sc, &width, &height);
	if (width == 0 || height == 0) {
		return NULL;
	}

	ED_clip_mouse_pos(sc, ar, event->mval, co);

	float min_distance_squared = FLT_MAX;
	int min_corner = -1;
	MovieTrackingPlaneTrack *min_plane_track = NULL;
	for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first;
	     plane_track != NULL;
	     plane_track = plane_track->next)
	{
		if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
			MovieTrackingPlaneMarker *plane_marker =
			        BKE_tracking_plane_marker_get(plane_track, framenr);
			for (int i = 0; i < 4; i++) {
				float distance_squared =
				        mouse_to_plane_slide_zone_distance_squared(
				                co,
				                plane_marker->corners[i],
				                width,
				                height);

				if (distance_squared < min_distance_squared) {
					min_distance_squared = distance_squared;
					min_corner = i;
					min_plane_track = plane_track;
				}
			}
		}
	}

	if (min_distance_squared < distance_clip_squared / sc->zoom) {
		if (corner_r != NULL) {
			*corner_r = min_corner;
		}
		return min_plane_track;
	}

	return NULL;
}
示例#4
0
static void draw_plane_track(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
                             int framenr, bool is_active_track, int width, int height)
{
	MovieTrackingPlaneMarker *plane_marker;

	plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);

	draw_plane_marker_outline(sc, scene, plane_track, plane_marker, width, height);
	draw_plane_marker(sc, scene, plane_track, plane_marker, is_active_track, width, height);
}
static MovieTrackingPlaneMarker *find_plane_keyframe(MovieTrackingPlaneTrack *plane_track,
                                                     int start_frame, int direction)
{
	MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
	int index = plane_marker - plane_track->markers;
	int frame_delta = direction > 0 ? 1 : -1;

	while (index >= 0 && index < plane_track->markersnr) {
		if ((plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
			return plane_marker;
		}
		plane_marker += frame_delta;
	}

	return NULL;
}
static void rna_Mask_update_parent(Main *bmain, Scene *scene, PointerRNA *ptr)
{
	MaskParent *parent = ptr->data;

	if (parent->id) {
		if (GS(parent->id->name) == ID_MC) {
			MovieClip *clip = (MovieClip *) parent->id;
			MovieTracking *tracking = &clip->tracking;
			MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, parent->parent);

			if (object) {
				int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra);

				if (parent->type == MASK_PARENT_POINT_TRACK) {
					MovieTrackingTrack *track = BKE_tracking_track_get_named(tracking, object, parent->sub_parent);

					if (track) {
						MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_framenr);
						float marker_pos_ofs[2], parmask_pos[2];
						MovieClipUser user = {0};

						BKE_movieclip_user_set_frame(&user, scene->r.cfra);

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

						BKE_mask_coord_from_movieclip(clip, &user, parmask_pos, marker_pos_ofs);

						copy_v2_v2(parent->parent_orig, parmask_pos);
					}
				}
				else /* if (parent->type == MASK_PARENT_PLANE_TRACK) */ {
					MovieTrackingPlaneTrack *plane_track = BKE_tracking_plane_track_get_named(tracking, object, parent->sub_parent);
					if (plane_track) {
						MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr);

						memcpy(parent->parent_corners_orig, plane_marker->corners, sizeof(parent->parent_corners_orig));
						zero_v2(parent->parent_orig);
					}
				}
			}
		}
	}

	rna_Mask_update_data(bmain, scene, ptr);
}
/* NOTE: frame number should be in clip space, not scene space */
static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame,
                                             int direction, bool retrack)
{
	MovieTrackingPlaneMarker *start_plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
	MovieTrackingPlaneMarker *keyframe_plane_marker = NULL;
	MovieTrackingPlaneMarker new_plane_marker;
	int current_frame, frame_delta = direction > 0 ? 1 : -1;

	if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
		/* Find a keyframe in given direction. */
		for (current_frame = start_frame; ; current_frame += frame_delta) {
			MovieTrackingPlaneMarker *next_plane_marker =
				BKE_tracking_plane_marker_get_exact(plane_track, current_frame + frame_delta);

			if (next_plane_marker == NULL) {
				break;
			}

			if ((next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
				keyframe_plane_marker = next_plane_marker;
				break;
			}
		}
	}
	else {
		start_plane_marker->flag |= PLANE_MARKER_TRACKED;
	}

	new_plane_marker = *start_plane_marker;
	new_plane_marker.flag |= PLANE_MARKER_TRACKED;

	for (current_frame = start_frame; ; current_frame += frame_delta) {
		MovieTrackingPlaneMarker *next_plane_marker =
			BKE_tracking_plane_marker_get_exact(plane_track, current_frame + frame_delta);
		Vec2 *x1, *x2;
		int i, num_correspondences;
		double H_double[3][3];
		float H[3][3];

		/* As soon as we meet keyframed plane, we stop updating the sequence. */
		if (next_plane_marker && (next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
			/* Don't override keyframes if track is in auto-keyframe mode */
			if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
				break;
			}
		}

		num_correspondences =
			point_markers_correspondences_on_both_image(plane_track, current_frame, current_frame + frame_delta,
			                                            &x1, &x2);

		if (num_correspondences < 4) {
			MEM_freeN(x1);
			MEM_freeN(x2);

			break;
		}

		libmv_homography2DFromCorrespondencesEuc(x1, x2, num_correspondences, H_double);

		copy_m3_m3d(H, H_double);

		for (i = 0; i < 4; i++) {
			float vec[3] = {0.0f, 0.0f, 1.0f}, vec2[3];
			copy_v2_v2(vec, new_plane_marker.corners[i]);

			/* Apply homography */
			mul_v3_m3v3(vec2, H, vec);

			/* Normalize. */
			vec2[0] /= vec2[2];
			vec2[1] /= vec2[2];

			copy_v2_v2(new_plane_marker.corners[i], vec2);
		}

		new_plane_marker.framenr = current_frame + frame_delta;

		if (!retrack && keyframe_plane_marker &&
		    next_plane_marker &&
		    (plane_track->flag & PLANE_TRACK_AUTOKEY))
		{
			float fac = ((float) next_plane_marker->framenr - start_plane_marker->framenr) /
			            ((float) keyframe_plane_marker->framenr - start_plane_marker->framenr);

			fac = 3 * fac * fac - 2 * fac * fac * fac;

			for (i = 0; i < 4; i++) {
				interp_v2_v2v2(new_plane_marker.corners[i], new_plane_marker.corners[i],
				               next_plane_marker->corners[i], fac);
			}
		}

		BKE_tracking_plane_marker_insert(plane_track, &new_plane_marker);

		MEM_freeN(x1);
		MEM_freeN(x2);
	}
}
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;
}
static int circle_select_exec(bContext *C, wmOperator *op)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	ARegion *ar = CTX_wm_region(C);

	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingTrack *track;
	MovieTrackingPlaneTrack *plane_track;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
	int x, y, radius, width, height, mode;
	bool changed = false;
	float zoomx, zoomy, offset[2], ellipse[2];
	int framenr = ED_space_clip_get_clip_frame_number(sc);

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

	mode = RNA_int_get(op->ptr, "gesture_mode");

	/* compute ellipse and position in unified coordinates */
	ED_space_clip_get_size(sc, &width, &height);
	ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);

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

	ED_clip_point_stable_pos(sc, ar, x, y, &offset[0], &offset[1]);

	/* do selection */
	track = tracksbase->first;
	while (track) {
		if ((track->flag & TRACK_HIDDEN) == 0) {
			MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);

			if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) {
				if (mode == GESTURE_MODAL_SELECT)
					BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT);
				else
					BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);

				changed = true;
			}
		}

		track = track->next;
	}

	for (plane_track = plane_tracks_base->first;
	     plane_track;
	     plane_track = plane_track->next)
	{
		if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
			MovieTrackingPlaneMarker *plane_marker =
				BKE_tracking_plane_marker_get(plane_track, framenr);
			int i;

			for (i = 0; i < 4; i++) {
				if (point_inside_ellipse(plane_marker->corners[i], offset, ellipse)) {
					if (mode == GESTURE_MODAL_SELECT) {
						plane_track->flag |= SELECT;
					}
					else {
						plane_track->flag &= ~SELECT;
					}
				}
			}

			changed = true;
		}
	}

	if (changed) {
		BKE_tracking_dopesheet_tag_update(tracking);

		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);

		return OPERATOR_FINISHED;
	}

	return OPERATOR_CANCELLED;
}
static int do_lasso_select_marker(bContext *C, const int mcords[][2], const short moves, bool select)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	ARegion *ar = CTX_wm_region(C);

	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingTrack *track;
	MovieTrackingPlaneTrack *plane_track;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
	rcti rect;
	bool changed = false;
	int framenr = ED_space_clip_get_clip_frame_number(sc);

	/* get rectangle from operator */
	BLI_lasso_boundbox(&rect, mcords, moves);

	/* do actual selection */
	track = tracksbase->first;
	while (track) {
		if ((track->flag & TRACK_HIDDEN) == 0) {
			MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);

			if (MARKER_VISIBLE(sc, track, marker)) {
				float screen_co[2];

				/* marker in screen coords */
				ED_clip_point_stable_pos__reverse(sc, ar, marker->pos, screen_co);

				if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
				    BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
				{
					if (select)
						BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT);
					else
						BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
				}

				changed = true;
			}
		}

		track = track->next;
	}

	for (plane_track = plane_tracks_base->first;
	     plane_track;
	     plane_track = plane_track->next)
	{
		if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
			MovieTrackingPlaneMarker *plane_marker =
				BKE_tracking_plane_marker_get(plane_track, framenr);
			int i;

			for (i = 0; i < 4; i++) {
				float screen_co[2];

				/* marker in screen coords */
				ED_clip_point_stable_pos__reverse(sc, ar, plane_marker->corners[i], screen_co);

				if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
				    BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
				{
					if (select) {
						plane_track->flag |= SELECT;
					}
					else {
						plane_track->flag &= ~SELECT;
					}
				}
			}

			changed = true;
		}
	}

	if (changed) {
		BKE_tracking_dopesheet_tag_update(tracking);

		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);
	}

	return changed;
}
static int border_select_exec(bContext *C, wmOperator *op)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	ARegion *ar = CTX_wm_region(C);

	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingTrack *track;
	MovieTrackingPlaneTrack *plane_track;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
	rcti rect;
	rctf rectf;
	bool changed = false;
	int mode, extend;
	int framenr = ED_space_clip_get_clip_frame_number(sc);

	/* get rectangle from operator */
	WM_operator_properties_border_to_rcti(op, &rect);

	ED_clip_point_stable_pos(sc, ar, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
	ED_clip_point_stable_pos(sc, ar, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);

	mode = RNA_int_get(op->ptr, "gesture_mode");
	extend = RNA_boolean_get(op->ptr, "extend");

	/* do actual selection */
	track = tracksbase->first;
	while (track) {
		if ((track->flag & TRACK_HIDDEN) == 0) {
			MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);

			if (MARKER_VISIBLE(sc, track, marker)) {
				if (BLI_rctf_isect_pt_v(&rectf, marker->pos)) {
					if (mode == GESTURE_MODAL_SELECT)
						BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT);
					else
						BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
				}
				else if (!extend) {
					BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
				}

				changed = true;
			}
		}

		track = track->next;
	}

	for (plane_track = plane_tracks_base->first;
	     plane_track;
	     plane_track = plane_track->next)
	{
		if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
			MovieTrackingPlaneMarker *plane_marker =
				BKE_tracking_plane_marker_get(plane_track, framenr);
			int i;

			for (i = 0; i < 4; i++) {
				if (BLI_rctf_isect_pt_v(&rectf, plane_marker->corners[i])) {
					if (mode == GESTURE_MODAL_SELECT) {
						plane_track->flag |= SELECT;
					}
					else {
						plane_track->flag &= ~SELECT;
					}
				}
				else if (!extend) {
					plane_track->flag &= ~SELECT;
				}
			}

			changed = true;
		}
	}

	if (changed) {
		BKE_tracking_dopesheet_tag_update(tracking);

		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);

		return OPERATOR_FINISHED;
	}

	return OPERATOR_CANCELLED;
}