예제 #1
0
void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata,
			void (*func) (void *userdata, MovieTrackingMarker *marker))
{
	MovieClip *clip= ED_space_clip(sc);
	MovieTracking *tracking= &clip->tracking;
	MovieTrackingTrack *track;

	track= tracking->tracks.first;
	while(track) {
		if(TRACK_VIEW_SELECTED(sc, track)) {
			int i;

			for(i= 0; i<track->markersnr; i++) {
				MovieTrackingMarker *marker= &track->markers[i];

				if(marker->flag&MARKER_DISABLED)
					continue;

				if(func)
					func(userdata, marker);
			}
		}

		track= track->next;
	}
}
예제 #2
0
static int set_origin_exec(bContext *C, wmOperator *op)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  MovieClip *clip = ED_space_clip_get_clip(sc);
  MovieTracking *tracking = &clip->tracking;
  Scene *scene = CTX_data_scene(C);
  Object *camera = get_camera_with_movieclip(scene, clip);
  int selected_count = count_selected_bundles(C);

  if (selected_count == 0) {
    BKE_report(op->reports,
               RPT_ERROR,
               "At least one track with bundle should be selected to "
               "define origin position");

    return OPERATOR_CANCELLED;
  }

  Object *object = get_orientation_object(C);
  if (object == NULL) {
    BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
    return OPERATOR_CANCELLED;
  }

  MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
  ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);

  float median[3] = {0.0f, 0.0f, 0.0f};
  zero_v3(median);
  for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) {
    if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) {
      add_v3_v3(median, track->bundle_pos);
    }
  }
  mul_v3_fl(median, 1.0f / selected_count);

  float mat[4][4], vec[3];
  BKE_tracking_get_camera_object_matrix(scene, camera, mat);
  mul_v3_m4v3(vec, mat, median);

  if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
    sub_v3_v3(object->loc, vec);
  }
  else {
    object_solver_inverted_matrix(scene, object, mat);
    mul_v3_m4v3(vec, mat, vec);
    copy_v3_v3(object->loc, vec);
  }

  DEG_id_tag_update(&clip->id, 0);
  DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM);

  WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
  WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);

  return OPERATOR_FINISHED;
}
예제 #3
0
static int count_selected_bundles(bContext *C)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  MovieClip *clip = ED_space_clip_get_clip(sc);
  ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
  int tot = 0;
  for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) {
    if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) {
      tot++;
    }
  }
  return tot;
}
예제 #4
0
static bool selected_boundbox(SpaceClip *sc, float min[2], float max[2])
{
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTrackingTrack *track;
	int width, height;
	bool ok = false;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
	int framenr = ED_space_clip_get_clip_frame_number(sc);

	INIT_MINMAX2(min, max);

	ED_space_clip_get_size(sc, &width, &height);

	track = tracksbase->first;
	while (track) {
		if (TRACK_VIEW_SELECTED(sc, track)) {
			MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);

			if (marker) {
				float pos[3];

				pos[0] = marker->pos[0] + track->offset[0];
				pos[1] = marker->pos[1] + track->offset[1];
				pos[2] = 0.0f;

				/* undistortion happens for normalized coords */
				if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
					/* undistortion happens for normalized coords */
					ED_clip_point_undistorted_pos(sc, pos, pos);
				}

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

				mul_v3_m4v3(pos, sc->stabmat, pos);

				minmax_v2v2_v2(min, max, pos);

				ok = true;
			}
		}

		track = track->next;
	}

	return ok;
}
예제 #5
0
static int set_axis_exec(bContext *C, wmOperator *op)
{
    SpaceClip *sc = CTX_wm_space_clip(C);
    MovieClip *clip = ED_space_clip_get_clip(sc);
    MovieTracking *tracking = &clip->tracking;
    MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
    Scene *scene = CTX_data_scene(C);
    Object *object;
    int axis = RNA_enum_get(op->ptr, "axis");

    if (count_selected_bundles(C) != 1) {
        BKE_report(op->reports,
                   RPT_ERROR,
                   "Single track with bundle should be selected to define axis");
        return OPERATOR_CANCELLED;
    }

    object = get_orientation_object(C);
    if (object == NULL) {
        BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
        return OPERATOR_CANCELLED;
    }

    ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking,
                           tracking_object);
    MovieTrackingTrack *track = tracksbase->first;
    while (track) {
        if (TRACK_VIEW_SELECTED(sc, track) &&
                (track->flag & TRACK_HAS_BUNDLE))
        {
            break;
        }
        track = track->next;
    }

    set_axis(scene, object, clip, tracking_object, track, axis == 0 ? 'X' : 'Y');

    DAG_id_tag_update(&clip->id, 0);
    DAG_id_tag_update(&object->id, OB_RECALC_OB);

    WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
    WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);

    return OPERATOR_FINISHED;
}
예제 #6
0
void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata,
			void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val),
			void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord),
			void (*segment_end) (void *userdata))
{
	MovieClip *clip= ED_space_clip(sc);
	MovieTracking *tracking= &clip->tracking;
	MovieTrackingTrack *track;

	track= tracking->tracks.first;
	while(track) {
		if(TRACK_VIEW_SELECTED(sc, track)) {
			clip_graph_tracking_values_iterate_track(sc, track, userdata, func, segment_start, segment_end);
		}

		track= track->next;
	}
}
예제 #7
0
static int mouse_select(bContext *C, float co[2], int extend)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
	MovieTrackingTrack *track = NULL;   /* selected marker */

	track = find_nearest_track(sc, tracksbase, co);

	if (track) {
		int area = track_mouse_area(C, co, track);

		if (!extend || !TRACK_VIEW_SELECTED(sc, track))
			area = TRACK_AREA_ALL;

		if (extend && TRACK_AREA_SELECTED(track, area)) {
			if (track == act_track)
				BKE_tracking_track_deselect(track, area);
			else
				clip->tracking.act_track = track;
		}
		else {
			if (area == TRACK_AREA_POINT)
				area = TRACK_AREA_ALL;

			BKE_tracking_track_select(tracksbase, track, area, extend);
			clip->tracking.act_track = track;
		}
	}

	if (!extend) {
		sc->xlockof = 0.0f;
		sc->ylockof = 0.0f;
	}

	BKE_tracking_dopesheet_tag_update(tracking);

	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);

	return OPERATOR_FINISHED;
}
예제 #8
0
static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2], float *distance_r)
{
	MovieTrackingTrack *track = NULL, *cur;
	float mindist = 0.0f;
	int framenr = ED_space_clip_get_clip_frame_number(sc);

	cur = tracksbase->first;
	while (cur) {
		MovieTrackingMarker *marker = BKE_tracking_marker_get(cur, framenr);

		if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) {
			float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX;

			/* distance to marker point */
			d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) +
			           (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1]));

			/* distance to pattern boundbox */
			if (sc->flag & SC_SHOW_MARKER_PATTERN)
				d2 = dist_to_crns(co, marker->pos, marker->pattern_corners);

			/* distance to search boundbox */
			if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur))
				d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max);

			/* choose minimal distance. useful for cases of overlapped markers. */
			dist = min_fff(d1, d2, d3);

			if (track == NULL || dist < mindist) {
				track = cur;
				mindist = dist;
			}
		}

		cur = cur->next;
	}

	*distance_r = mindist;

	return track;
}
예제 #9
0
static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
                              const float marker_pos[2], int width, int height, int act, int sel)
{
	int tiny = sc->flag & SC_SHOW_TINY_MARKER;
	bool show_search = false;
	float col[3], scol[3], px[2];

	track_colors(track, act, col, scol);

	px[0] = 1.0f / width / sc->zoom;
	px[1] = 1.0f / height / sc->zoom;

	/* marker position and offset position */
	if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) {
		float pos[2], p[2];

		if (track->flag & TRACK_LOCKED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->flag & SELECT)
				UI_ThemeColorShade(TH_LOCK_MARKER, 64);
			else
				UI_ThemeColor(TH_LOCK_MARKER);
		}
		else {
			if (track->flag & SELECT)
				glColor3fv(scol);
			else
				glColor3fv(col);
		}

		add_v2_v2v2(pos, marker->pos, track->offset);
		ED_clip_point_undistorted_pos(sc, pos, pos);

		sub_v2_v2v2(p, pos, marker_pos);

		if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
		                        marker->pattern_corners[2], marker->pattern_corners[3]))
		{
			if (!tiny)
				glPointSize(2.0f);

			glBegin(GL_POINTS);
			glVertex2f(pos[0], pos[1]);
			glEnd();

			if (!tiny)
				glPointSize(1.0f);
		}
		else {
			glBegin(GL_LINES);
			glVertex2f(pos[0] + px[0] * 3, pos[1]);
			glVertex2f(pos[0] + px[0] * 7, pos[1]);

			glVertex2f(pos[0] - px[0] * 3, pos[1]);
			glVertex2f(pos[0] - px[0] * 7, pos[1]);

			glVertex2f(pos[0], pos[1] - px[1] * 3);
			glVertex2f(pos[0], pos[1] - px[1] * 7);

			glVertex2f(pos[0], pos[1] + px[1] * 3);
			glVertex2f(pos[0], pos[1] + px[1] * 7);
			glEnd();

			glColor3f(0.0f, 0.0f, 0.0f);
			glLineStipple(3, 0xaaaa);
			glEnable(GL_LINE_STIPPLE);
			glEnable(GL_COLOR_LOGIC_OP);
			glLogicOp(GL_NOR);

			glBegin(GL_LINES);
			glVertex2fv(pos);
			glVertex2fv(marker_pos);
			glEnd();

			glDisable(GL_COLOR_LOGIC_OP);
			glDisable(GL_LINE_STIPPLE);
		}
	}

	/* pattern */
	glPushMatrix();
	glTranslatef(marker_pos[0], marker_pos[1], 0);

	if (tiny) {
		glLineStipple(3, 0xaaaa);
		glEnable(GL_LINE_STIPPLE);
	}

	if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
		if (track->flag & TRACK_LOCKED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->pat_flag & SELECT)
				UI_ThemeColorShade(TH_LOCK_MARKER, 64);
			else UI_ThemeColor(TH_LOCK_MARKER);
		}
		else if (marker->flag & MARKER_DISABLED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->pat_flag & SELECT)
				UI_ThemeColorShade(TH_DIS_MARKER, 128);
			else UI_ThemeColor(TH_DIS_MARKER);
		}
		else {
			if (track->pat_flag & SELECT)
				glColor3fv(scol);
			else glColor3fv(col);
		}

		glBegin(GL_LINE_LOOP);
		glVertex2fv(marker->pattern_corners[0]);
		glVertex2fv(marker->pattern_corners[1]);
		glVertex2fv(marker->pattern_corners[2]);
		glVertex2fv(marker->pattern_corners[3]);
		glEnd();
	}

	/* search */
	show_search = (TRACK_VIEW_SELECTED(sc, track) &&
	               ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
	if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
		if (track->flag & TRACK_LOCKED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->search_flag & SELECT)
				UI_ThemeColorShade(TH_LOCK_MARKER, 64);
			else UI_ThemeColor(TH_LOCK_MARKER);
		}
		else if (marker->flag & MARKER_DISABLED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->search_flag & SELECT)
				UI_ThemeColorShade(TH_DIS_MARKER, 128);
			else UI_ThemeColor(TH_DIS_MARKER);
		}
		else {
			if (track->search_flag & SELECT)
				glColor3fv(scol);
			else
				glColor3fv(col);
		}

		glBegin(GL_LINE_LOOP);
		glVertex2f(marker->search_min[0], marker->search_min[1]);
		glVertex2f(marker->search_max[0], marker->search_min[1]);
		glVertex2f(marker->search_max[0], marker->search_max[1]);
		glVertex2f(marker->search_min[0], marker->search_max[1]);
		glEnd();
	}

	if (tiny)
		glDisable(GL_LINE_STIPPLE);

	glPopMatrix();
}
예제 #10
0
static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
                                const float marker_pos[2], int width, int height)
{
	int tiny = sc->flag & SC_SHOW_TINY_MARKER;
	bool show_search = false;
	float px[2];

	UI_ThemeColor(TH_MARKER_OUTLINE);

	px[0] = 1.0f / width / sc->zoom;
	px[1] = 1.0f / height / sc->zoom;

	if ((marker->flag & MARKER_DISABLED) == 0) {
		float pos[2];
		float p[2];

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

		ED_clip_point_undistorted_pos(sc, pos, pos);

		sub_v2_v2v2(p, pos, marker_pos);

		if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
		                        marker->pattern_corners[2], marker->pattern_corners[3]))
		{
			if (tiny) glPointSize(3.0f);
			else glPointSize(4.0f);
			glBegin(GL_POINTS);
			glVertex2f(pos[0], pos[1]);
			glEnd();
			glPointSize(1.0f);
		}
		else {
			if (!tiny) glLineWidth(3.0f);
			glBegin(GL_LINES);
			glVertex2f(pos[0] + px[0] * 2, pos[1]);
			glVertex2f(pos[0] + px[0] * 8, pos[1]);

			glVertex2f(pos[0] - px[0] * 2, pos[1]);
			glVertex2f(pos[0] - px[0] * 8, pos[1]);

			glVertex2f(pos[0], pos[1] - px[1] * 2);
			glVertex2f(pos[0], pos[1] - px[1] * 8);

			glVertex2f(pos[0], pos[1] + px[1] * 2);
			glVertex2f(pos[0], pos[1] + px[1] * 8);
			glEnd();
			if (!tiny) glLineWidth(1.0f);
		}
	}

	/* pattern and search outline */
	glPushMatrix();
	glTranslatef(marker_pos[0], marker_pos[1], 0);

	if (!tiny)
		glLineWidth(3.0f);

	if (sc->flag & SC_SHOW_MARKER_PATTERN) {
		glBegin(GL_LINE_LOOP);
		glVertex2fv(marker->pattern_corners[0]);
		glVertex2fv(marker->pattern_corners[1]);
		glVertex2fv(marker->pattern_corners[2]);
		glVertex2fv(marker->pattern_corners[3]);
		glEnd();
	}

	show_search = (TRACK_VIEW_SELECTED(sc, track) &&
	               ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
	if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) {
		glBegin(GL_LINE_LOOP);
		glVertex2f(marker->search_min[0], marker->search_min[1]);
		glVertex2f(marker->search_max[0], marker->search_min[1]);
		glVertex2f(marker->search_max[0], marker->search_max[1]);
		glVertex2f(marker->search_min[0], marker->search_max[1]);
		glEnd();
	}
	glPopMatrix();

	if (!tiny)
		glLineWidth(1.0f);
}
예제 #11
0
static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
{
	int count = sc->path_length;
	int i, a, b, curindex = -1;
	float path[102][2];
	int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame;
	MovieTrackingMarker *marker;

	if (count == 0)
		return;

	start_frame = framenr = ED_space_clip_get_clip_frame_number(sc);

	marker = BKE_tracking_marker_get(track, framenr);
	if (marker->framenr != framenr || marker->flag & MARKER_DISABLED)
		return;

	a = count;
	i = framenr - 1;
	while (i >= framenr - count) {
		marker = BKE_tracking_marker_get(track, i);

		if (!marker || marker->flag & MARKER_DISABLED)
			break;

		if (marker->framenr == i) {
			add_v2_v2v2(path[--a], marker->pos, track->offset);
			ED_clip_point_undistorted_pos(sc, path[a], path[a]);

			if (marker->framenr == start_frame)
				curindex = a;
		}
		else {
			break;
		}

		i--;
	}

	b = count;
	i = framenr;
	while (i <= framenr + count) {
		marker = BKE_tracking_marker_get(track, i);

		if (!marker || marker->flag & MARKER_DISABLED)
			break;

		if (marker->framenr == i) {
			if (marker->framenr == start_frame)
				curindex = b;

			add_v2_v2v2(path[b++], marker->pos, track->offset);
			ED_clip_point_undistorted_pos(sc, path[b - 1], path[b - 1]);
		}
		else
			break;

		i++;
	}

	if (!tiny) {
		UI_ThemeColor(TH_MARKER_OUTLINE);

		if (TRACK_VIEW_SELECTED(sc, track)) {
			glPointSize(5.0f);
			glBegin(GL_POINTS);
			for (i = a; i < b; i++) {
				if (i != curindex)
					glVertex2f(path[i][0], path[i][1]);
			}
			glEnd();
		}

		glLineWidth(3.0f);
		glBegin(GL_LINE_STRIP);
		for (i = a; i < b; i++)
			glVertex2f(path[i][0], path[i][1]);
		glEnd();
		glLineWidth(1.0f);
	}

	UI_ThemeColor(TH_PATH_BEFORE);

	if (TRACK_VIEW_SELECTED(sc, track)) {
		glPointSize(3.0f);
		glBegin(GL_POINTS);
		for (i = a; i < b; i++) {
			if (i == count + 1)
				UI_ThemeColor(TH_PATH_AFTER);

			if (i != curindex)
				glVertex2f(path[i][0], path[i][1]);
		}
		glEnd();
	}

	UI_ThemeColor(TH_PATH_BEFORE);

	glBegin(GL_LINE_STRIP);
	for (i = a; i < b; i++) {
		if (i == count + 1)
			UI_ThemeColor(TH_PATH_AFTER);

		glVertex2f(path[i][0], path[i][1]);
	}
	glEnd();
	glPointSize(1.0f);
}
예제 #12
0
static int mouse_select(bContext *C, float co[2], int extend)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
	MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
	MovieTrackingTrack *track;
	MovieTrackingPlaneTrack *plane_track;
	float distance_to_track, distance_to_plane_track;

	track = find_nearest_track(sc, tracksbase, co, &distance_to_track);
	plane_track = find_nearest_plane_track(sc, plane_tracks_base, co, &distance_to_plane_track);

	/* Between track and plane we choose closest to the mouse for selection here. */
	if (track && plane_track) {
		if (distance_to_track < distance_to_plane_track) {
			plane_track = NULL;
		}
		else {
			track = NULL;
		}
	}

	if (!extend) {
		delect_all_plane_tracks(plane_tracks_base);
	}

	if (track) {
		int area = track_mouse_area(C, co, track);

		if (!extend || !TRACK_VIEW_SELECTED(sc, track))
			area = TRACK_AREA_ALL;

		if (extend && TRACK_AREA_SELECTED(track, area)) {
			if (track == act_track) {
				BKE_tracking_track_deselect(track, area);
			}
			else {
				clip->tracking.act_track = track;
				clip->tracking.act_plane_track = NULL;
			}
		}
		else {
			if (area == TRACK_AREA_POINT)
				area = TRACK_AREA_ALL;

			BKE_tracking_track_select(tracksbase, track, area, extend);
			clip->tracking.act_track = track;
			clip->tracking.act_plane_track = NULL;
		}
	}
	else if (plane_track) {
		if (!extend) {
			delect_all_tracks(tracksbase);
		}

		if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
			if (extend) {
				plane_track->flag &= ~SELECT;
			}
		}
		else {
			plane_track->flag |= SELECT;
		}

		clip->tracking.act_track = NULL;
		clip->tracking.act_plane_track = plane_track;
	}

	if (!extend) {
		sc->xlockof = 0.0f;
		sc->ylockof = 0.0f;
	}

	BKE_tracking_dopesheet_tag_update(tracking);

	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);

	return OPERATOR_FINISHED;
}
예제 #13
0
static int do_set_scale(bContext *C, wmOperator *op, bool scale_solution, bool apply_scale)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  MovieClip *clip = ED_space_clip_get_clip(sc);
  MovieTracking *tracking = &clip->tracking;
  MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
  MovieTrackingTrack *track;
  Scene *scene = CTX_data_scene(C);
  Object *object = NULL;
  Object *camera = get_camera_with_movieclip(scene, clip);
  ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
  int tot = 0;
  float vec[2][3], mat[4][4], scale;
  float dist = RNA_float_get(op->ptr, "distance");

  if (count_selected_bundles(C) != 2) {
    BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to set scale");
    return OPERATOR_CANCELLED;
  }

  if (!scale_solution && !apply_scale) {
    object = get_orientation_object(C);
    if (object == NULL) {
      BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
      return OPERATOR_CANCELLED;
    }
  }

  BKE_tracking_get_camera_object_matrix(scene, camera, mat);

  track = tracksbase->first;
  while (track) {
    if (TRACK_VIEW_SELECTED(sc, track)) {
      mul_v3_m4v3(vec[tot], mat, track->bundle_pos);
      tot++;
    }
    track = track->next;
  }

  sub_v3_v3(vec[0], vec[1]);

  if (len_v3(vec[0]) > 1e-5f) {
    scale = dist / len_v3(vec[0]);
    if (apply_scale) {
      /* Apply scale on reconstructed scene itself. */
      MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(
          tracking);
      MovieReconstructedCamera *reconstructed_cameras;
      int i;

      for (track = tracksbase->first; track; track = track->next) {
        mul_v3_fl(track->bundle_pos, scale);
      }

      reconstructed_cameras = reconstruction->cameras;
      for (i = 0; i < reconstruction->camnr; i++) {
        mul_v3_fl(reconstructed_cameras[i].mat[3], scale);
      }

      WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
      WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
    }
    else {
      if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
        mul_v3_fl(object->scale, scale);
        mul_v3_fl(object->loc, scale);
      }
      else if (!scale_solution) {
        Object *solver_camera = object_solver_camera(scene, object);

        object->scale[0] = object->scale[1] = object->scale[2] = 1.0f / scale;

        if (solver_camera) {
          object->scale[0] /= solver_camera->scale[0];
          object->scale[1] /= solver_camera->scale[1];
          object->scale[2] /= solver_camera->scale[2];
        }
      }
      else {
        tracking_object->scale = scale;
      }

      DEG_id_tag_update(&clip->id, 0);

      if (object) {
        DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM);
      }

      WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
      WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
    }
  }

  return OPERATOR_FINISHED;
}
예제 #14
0
static int set_plane_exec(bContext *C, wmOperator *op)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  MovieClip *clip = ED_space_clip_get_clip(sc);
  Scene *scene = CTX_data_scene(C);
  MovieTracking *tracking = &clip->tracking;
  MovieTrackingObject *tracking_object;
  MovieTrackingTrack *track, *axis_track = NULL, *act_track;
  ListBase *tracksbase;
  Object *object;
  Object *camera = get_camera_with_movieclip(scene, clip);
  Depsgraph *depsgraph = CTX_data_depsgraph(C);
  int tot = 0;
  float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3] = {0.0f, 0.0f, 0.0f};
  int plane = RNA_enum_get(op->ptr, "plane");
  float rot[4][4] = {
      {0.0f, 0.0f, -1.0f, 0.0f},
      {0.0f, 1.0f, 0.0f, 0.0f},
      {1.0f, 0.0f, 0.0f, 0.0f},
      {0.0f, 0.0f, 0.0f, 1.0f},
  }; /* 90 degrees Y-axis rotation matrix */

  if (count_selected_bundles(C) != 3) {
    BKE_report(op->reports, RPT_ERROR, "Three tracks with bundles are needed to orient the floor");

    return OPERATOR_CANCELLED;
  }

  tracking_object = BKE_tracking_object_get_active(tracking);
  tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
  act_track = BKE_tracking_track_get_active(tracking);

  object = get_orientation_object(C);
  if (object == NULL) {
    BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
    return OPERATOR_CANCELLED;
  }

  BKE_tracking_get_camera_object_matrix(scene, camera, mat);

  /* Get 3 bundles to use as reference. */
  track = tracksbase->first;
  while (track && tot < 3) {
    if (track->flag & TRACK_HAS_BUNDLE && TRACK_VIEW_SELECTED(sc, track)) {
      mul_v3_m4v3(vec[tot], mat, track->bundle_pos);
      if (tot == 0 || track == act_track) {
        copy_v3_v3(orig, vec[tot]);
      }
      else {
        axis_track = track;
      }
      tot++;
    }
    track = track->next;
  }

  sub_v3_v3(vec[1], vec[0]);
  sub_v3_v3(vec[2], vec[0]);

  /* Construct ortho-normal basis. */
  unit_m4(mat);
  if (plane == 0) { /* floor */
    cross_v3_v3v3(mat[0], vec[1], vec[2]);
    copy_v3_v3(mat[1], vec[1]);
    cross_v3_v3v3(mat[2], mat[0], mat[1]);
  }
  else if (plane == 1) { /* wall */
    cross_v3_v3v3(mat[2], vec[1], vec[2]);
    copy_v3_v3(mat[1], vec[1]);
    cross_v3_v3v3(mat[0], mat[1], mat[2]);
  }

  normalize_v3(mat[0]);
  normalize_v3(mat[1]);
  normalize_v3(mat[2]);

  /* Move to origin point. */
  mat[3][0] = orig[0];
  mat[3][1] = orig[1];
  mat[3][2] = orig[2];

  if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
    invert_m4(mat);

    BKE_object_to_mat4(object, obmat);
    mul_m4_m4m4(mat, mat, obmat);
    mul_m4_m4m4(newmat, rot, mat);
    BKE_object_apply_mat4(object, newmat, 0, 0);

    /* Make camera have positive z-coordinate. */
    if (object->loc[2] < 0) {
      invert_m4(rot);
      mul_m4_m4m4(newmat, rot, mat);
      BKE_object_apply_mat4(object, newmat, 0, 0);
    }
  }
  else {
    BKE_object_apply_mat4(object, mat, 0, 0);
  }

  BKE_object_where_is_calc(depsgraph, scene, object);
  set_axis(scene, object, clip, tracking_object, axis_track, 'X');

  DEG_id_tag_update(&clip->id, 0);
  DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM);

  WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
  WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);

  return OPERATOR_FINISHED;
}
예제 #15
0
static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
                                    const float marker_pos[2], int outline, int sel, int act, int width, int height)
{
	float dx, dy, patdx, patdy, searchdx, searchdy;
	int tiny = sc->flag & SC_SHOW_TINY_MARKER;
	float col[3], scol[3], px[2], side;

	if ((tiny && outline) || (marker->flag & MARKER_DISABLED))
		return;

	if (!TRACK_VIEW_SELECTED(sc, track) || track->flag & TRACK_LOCKED)
		return;

	track_colors(track, act, col, scol);

	if (outline) {
		glLineWidth(3.0f);
		UI_ThemeColor(TH_MARKER_OUTLINE);
	}

	glPushMatrix();
	glTranslatef(marker_pos[0], marker_pos[1], 0);

	dx = 6.0f / width / sc->zoom;
	dy = 6.0f / height / sc->zoom;

	side = get_shortest_pattern_side(marker);
	patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f) * UI_DPI_FAC;
	patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f) * UI_DPI_FAC;

	searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f) * UI_DPI_FAC;
	searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f) * UI_DPI_FAC;

	px[0] = 1.0f / sc->zoom / width / sc->scale;
	px[1] = 1.0f / sc->zoom / height / sc->scale;

	if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((track->search_flag & SELECT) == sel || outline)) {
		if (!outline) {
			if (track->search_flag & SELECT)
				glColor3fv(scol);
			else
				glColor3fv(col);
		}

		/* search offset square */
		draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px);

		/* search re-sizing triangle */
		draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px);
	}

	if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) {
		int i;
		float pat_min[2], pat_max[2];
/*		float dx = 12.0f / width, dy = 12.0f / height;*/ /* XXX UNUSED */
		float tilt_ctrl[2];

		if (!outline) {
			if (track->pat_flag & SELECT)
				glColor3fv(scol);
			else
				glColor3fv(col);
		}

		/* pattern's corners sliding squares */
		for (i = 0; i < 4; i++) {
			draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1],
			                         patdx / 1.5f, patdy / 1.5f, outline, px);
		}

		/* ** sliders to control overall pattern  ** */
		add_v2_v2v2(tilt_ctrl, marker->pattern_corners[1], marker->pattern_corners[2]);

		BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);

		glEnable(GL_LINE_STIPPLE);
		glLineStipple(3, 0xaaaa);

#if 0
		/* TODO: disable for now, needs better approach visualizing this */

		glBegin(GL_LINE_LOOP);
		glVertex2f(pat_min[0] - dx, pat_min[1] - dy);
		glVertex2f(pat_max[0] + dx, pat_min[1] - dy);
		glVertex2f(pat_max[0] + dx, pat_max[1] + dy);
		glVertex2f(pat_min[0] - dx, pat_max[1] + dy);
		glEnd();

		/* marker's offset slider */
		draw_marker_slide_square(pat_min[0] - dx, pat_max[1] + dy, patdx, patdy, outline, px);

		/* pattern re-sizing triangle */
		draw_marker_slide_triangle(pat_max[0] + dx, pat_min[1] - dy, patdx, patdy, outline, px);
#endif

		glBegin(GL_LINES);
		glVertex2f(0.0f, 0.0f);
		glVertex2fv(tilt_ctrl);
		glEnd();

		glDisable(GL_LINE_STIPPLE);


		/* slider to control pattern tilt */
		draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px);
	}

	glPopMatrix();

	if (outline)
		glLineWidth(1.0f);
}
예제 #16
0
static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
                              const float marker_pos[2], int act, int width, int height, float zoomx, float zoomy)
{
	char str[128] = {0}, state[64] = {0};
	float dx = 0.0f, dy = 0.0f, fontsize, pos[3];
	uiStyle *style = U.uistyles.first;
	int fontid = style->widget.uifont_id;

	if (!TRACK_VIEW_SELECTED(sc, track))
		return;

	BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
	fontsize = BLF_height_max(fontid);

	if (marker->flag & MARKER_DISABLED) {
		if (act)
			UI_ThemeColor(TH_ACT_MARKER);
		else
			UI_ThemeColorShade(TH_DIS_MARKER, 128);
	}
	else {
		if (act)
			UI_ThemeColor(TH_ACT_MARKER);
		else
			UI_ThemeColor(TH_SEL_MARKER);
	}

	if ((sc->flag & SC_SHOW_MARKER_SEARCH) &&
	    ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0))
	{
		dx = marker->search_min[0];
		dy = marker->search_min[1];
	}
	else if (sc->flag & SC_SHOW_MARKER_PATTERN) {
		float pat_min[2], pat_max[2];

		BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
		dx = pat_min[0];
		dy = pat_min[1];
	}

	pos[0] = (marker_pos[0] + dx) * width;
	pos[1] = (marker_pos[1] + dy) * height;
	pos[2] = 0.0f;

	mul_m4_v3(sc->stabmat, pos);

	pos[0] = pos[0] * zoomx;
	pos[1] = pos[1] * zoomy - fontsize;

	if (marker->flag & MARKER_DISABLED)
		strcpy(state, "disabled");
	else if (marker->framenr != ED_space_clip_get_clip_frame_number(sc))
		strcpy(state, "estimated");
	else if (marker->flag & MARKER_TRACKED)
		strcpy(state, "tracked");
	else
		strcpy(state, "keyframed");

	if (state[0])
		BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
	else
		BLI_strncpy(str, track->name, sizeof(str));

	BLF_position(fontid, pos[0], pos[1], 0.0f);
	BLF_draw(fontid, str, sizeof(str));
	pos[1] -= fontsize;

	if (track->flag & TRACK_HAS_BUNDLE) {
		BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
		BLF_position(fontid, pos[0], pos[1], 0.0f);
		BLF_draw(fontid, str, sizeof(str));
		pos[1] -= fontsize;
	}

	if (track->flag & TRACK_LOCKED) {
		BLF_position(fontid, pos[0], pos[1], 0.0f);
		BLF_draw(fontid, "locked", 6);
	}
}
예제 #17
0
static int select_all_exec(bContext *C, wmOperator *op)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingTrack *track = NULL;   /* selected track */
	MovieTrackingPlaneTrack *plane_track = NULL;   /* selected plane track */
	MovieTrackingMarker *marker;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
	int action = RNA_enum_get(op->ptr, "action");
	int framenr = ED_space_clip_get_clip_frame_number(sc);
	bool has_selection = false;

	if (action == SEL_TOGGLE) {
		action = SEL_SELECT;

		for (track = tracksbase->first; track; track = track->next) {
			if (TRACK_VIEW_SELECTED(sc, track)) {
				marker = BKE_tracking_marker_get(track, framenr);

				if (MARKER_VISIBLE(sc, track, marker)) {
					action = SEL_DESELECT;
					break;
				}
			}
		}

		for (plane_track = plane_tracks_base->first;
		     plane_track;
		     plane_track = plane_track->next)
		{
			if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
				action = SEL_DESELECT;
				break;
			}
		}
	}

	for (track = tracksbase->first; track; track = track->next) {
		if ((track->flag & TRACK_HIDDEN) == 0) {
			marker = BKE_tracking_marker_get(track, framenr);

			if (MARKER_VISIBLE(sc, track, marker)) {
				switch (action) {
					case SEL_SELECT:
						track->flag |= SELECT;
						track->pat_flag |= SELECT;
						track->search_flag |= SELECT;
						break;
					case SEL_DESELECT:
						track->flag &= ~SELECT;
						track->pat_flag &= ~SELECT;
						track->search_flag &= ~SELECT;
						break;
					case SEL_INVERT:
						track->flag ^= SELECT;
						track->pat_flag ^= SELECT;
						track->search_flag ^= SELECT;
						break;
				}
			}
		}

		if (TRACK_VIEW_SELECTED(sc, track))
			has_selection = true;
	}

	for (plane_track = plane_tracks_base->first;
	     plane_track;
	     plane_track = plane_track->next)
	{
		if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
			switch (action) {
				case SEL_SELECT:
					plane_track->flag |= SELECT;
					break;
				case SEL_DESELECT:
					plane_track->flag &= ~SELECT;
					break;
				case SEL_INVERT:
					plane_track->flag ^= SELECT;
					break;
			}
			if (plane_track->flag & SELECT) {
				has_selection = true;
			}
		}
	}

	if (!has_selection)
		sc->flag &= ~SC_LOCK_SELECTION;

	BKE_tracking_dopesheet_tag_update(tracking);

	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);

	return OPERATOR_FINISHED;
}