예제 #1
0
static void clip_draw_dopesheet_background(ARegion *ar, MovieClip *clip, unsigned int pos_id)
{
  View2D *v2d = &ar->v2d;
  MovieTracking *tracking = &clip->tracking;
  MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
  MovieTrackingDopesheetCoverageSegment *coverage_segment;

  for (coverage_segment = dopesheet->coverage_segments.first; coverage_segment;
       coverage_segment = coverage_segment->next) {
    if (coverage_segment->coverage < TRACKING_COVERAGE_OK) {
      int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
                                                                coverage_segment->start_frame);
      int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, coverage_segment->end_frame);

      if (coverage_segment->coverage == TRACKING_COVERAGE_BAD) {
        immUniformColor4f(1.0f, 0.0f, 0.0f, 0.07f);
      }
      else {
        immUniformColor4f(1.0f, 1.0f, 0.0f, 0.07f);
      }

      immRectf(pos_id, start_frame, v2d->cur.ymin, end_frame, v2d->cur.ymax);
    }
  }
}
예제 #2
0
static void draw_frame_curves(SpaceClip *sc)
{
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
	int i, lines = 0, prevfra = 0;

	glColor3f(0.0f, 0.0f, 1.0f);

	for (i = 0; i < reconstruction->camnr; i++) {
		MovieReconstructedCamera *camera = &reconstruction->cameras[i];
		int framenr;

		if (lines && camera->framenr != prevfra + 1) {
			glEnd();
			lines = 0;
		}

		if (!lines) {
			glBegin(GL_LINE_STRIP);
			lines = 1;
		}

		framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, camera->framenr);
		glVertex2f(framenr, camera->error);

		prevfra = camera->framenr;
	}

	if (lines)
		glEnd();
}
예제 #3
0
void clip_graph_tracking_values_iterate_track(
        SpaceClip *sc, MovieTrackingTrack *track, void *userdata,
        void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord,
                     int scene_framenr, float val),
        void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord),
        void (*segment_end)(void *userdata, int coord))
{
	MovieClip *clip = ED_space_clip_get_clip(sc);
	int width, height, coord;

	BKE_movieclip_get_size(clip, &sc->user, &width, &height);

	for (coord = 0; coord < 2; coord++) {
		int i, prevfra = 0;
		bool open = false;
		float prevval = 0.0f;

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

			if (marker->flag & MARKER_DISABLED) {
				if (open) {
					if (segment_end)
						segment_end(userdata, coord);

					open = false;
				}

				continue;
			}

			if (!open) {
				if (segment_start)
					segment_start(userdata, track, coord);

				open = true;
				prevval = marker->pos[coord];
			}

			/* value is a pixels per frame speed */
			val = (marker->pos[coord] - prevval) * ((coord == 0) ? (width) : (height));
			val /= marker->framenr - prevfra;

			if (func) {
				int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);

				func(userdata, track, marker, coord, scene_framenr, val);
			}

			prevval = marker->pos[coord];
			prevfra = marker->framenr;
		}

		if (open) {
			if (segment_end)
				segment_end(userdata, coord);
		}
	}
}
예제 #4
0
/* Get image buffer for a given frame
 *
 * Frame is in clip space.
 */
static ImBuf *tracking_context_get_frame_ibuf(MovieClip *clip, MovieClipUser *user, int clip_flag, int framenr)
{
	ImBuf *ibuf;
	MovieClipUser new_user = *user;

	new_user.framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, framenr);

	ibuf = BKE_movieclip_get_ibuf_flag(clip, &new_user, clip_flag, MOVIECLIP_CACHE_SKIP);

	return ibuf;
}
예제 #5
0
static ImBuf *accessor_get_preprocessed_ibuf(TrackingImageAccessor *accessor,
                                             int clip_index,
                                             int frame)
{
	MovieClip *clip;
	MovieClipUser user;
	ImBuf *ibuf;
	int scene_frame;

	BLI_assert(clip_index < accessor->num_clips);

	clip = accessor->clips[clip_index];
	scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame);
	BKE_movieclip_user_set_frame(&user, scene_frame);
	user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
	user.render_flag = 0;
	ibuf = BKE_movieclip_get_ibuf(clip, &user);

	return ibuf;
}
예제 #6
0
/* Create new libmv Tracks structure from blender's tracks list. */
static struct libmv_Tracks *libmv_tracks_new(MovieClip *clip, ListBase *tracksbase, int width, int height)
{
	int tracknr = 0;
	MovieTrackingTrack *track;
	struct libmv_Tracks *tracks = libmv_tracksNew();

	track = tracksbase->first;
	while (track) {
		FCurve *weight_fcurve;
		int a = 0;

		weight_fcurve = id_data_find_fcurve(&clip->id, track, &RNA_MovieTrackingTrack,
		                                    "weight", 0, NULL);

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

			if ((marker->flag & MARKER_DISABLED) == 0) {
				float weight = track->weight;

				if (weight_fcurve) {
					int scene_framenr =
						BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
					weight = evaluate_fcurve(weight_fcurve, scene_framenr);
				}

				libmv_tracksInsert(tracks, marker->framenr, tracknr,
				                   (marker->pos[0] + track->offset[0]) * width,
				                   (marker->pos[1] + track->offset[1]) * height,
				                   weight);
			}
		}

		track = track->next;
		tracknr++;
	}

	return tracks;
}
예제 #7
0
void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
{
  MovieClip *clip = ED_space_clip_get_clip(sc);
  View2D *v2d = &ar->v2d;

  /* frame range */
  clip_draw_sfra_efra(v2d, scene);

  if (clip) {
    MovieTracking *tracking = &clip->tracking;
    MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
    MovieTrackingDopesheetChannel *channel;
    float strip[4], selected_strip[4];
    float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);

    uint keyframe_len = 0;

    GPUVertFormat *format = immVertexFormat();
    uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
    immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);

    /* don't use totrect set, as the width stays the same
     * (NOTE: this is ok here, the configuration is pretty straightforward)
     */
    v2d->tot.ymin = (float)(-height);

    float y = (float)CHANNEL_FIRST;

    /* setup colors for regular and selected strips */
    UI_GetThemeColor3fv(TH_STRIP, strip);
    UI_GetThemeColor3fv(TH_STRIP_SELECT, selected_strip);

    strip[3] = 0.5f;
    selected_strip[3] = 1.0f;

    GPU_blend(true);

    clip_draw_dopesheet_background(ar, clip, pos_id);

    for (channel = dopesheet->channels.first; channel; channel = channel->next) {
      float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
      float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);

      /* check if visible */
      if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
          IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
        MovieTrackingTrack *track = channel->track;
        int i;
        bool sel = (track->flag & TRACK_DOPE_SEL) != 0;

        /* selection background */
        if (sel) {
          float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
          float default_color[4] = {0.8f, 0.93f, 0.8f, 0.3f};

          track_channel_color(track, default_color, color);
          immUniformColor4fv(color);

          immRectf(pos_id,
                   v2d->cur.xmin,
                   (float)y - CHANNEL_HEIGHT_HALF,
                   v2d->cur.xmax + EXTRA_SCROLL_PAD,
                   (float)y + CHANNEL_HEIGHT_HALF);
        }

        /* tracked segments */
        for (i = 0; i < channel->tot_segment; i++) {
          int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
                                                                    channel->segments[2 * i]);
          int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
                                                                  channel->segments[2 * i + 1]);

          immUniformColor4fv(sel ? selected_strip : strip);

          if (start_frame != end_frame) {
            immRectf(pos_id,
                     start_frame,
                     (float)y - STRIP_HEIGHT_HALF,
                     end_frame,
                     (float)y + STRIP_HEIGHT_HALF);
            keyframe_len += 2;
          }
          else {
            keyframe_len++;
          }
        }

        /* keyframes */
        i = 0;
        while (i < track->markersnr) {
          MovieTrackingMarker *marker = &track->markers[i];

          if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) {
            keyframe_len++;
          }

          i++;
        }
      }

      /* adjust y-position for next one */
      y -= CHANNEL_STEP;
    }

    immUnbindProgram();

    if (keyframe_len > 0) {
      /* draw keyframe markers */
      format = immVertexFormat();
      pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
      uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
      uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
      uint outline_color_id = GPU_vertformat_attr_add(
          format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
      uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);

      immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
      GPU_program_point_size(true);
      immUniform2f(
          "ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
      immBegin(GPU_PRIM_POINTS, keyframe_len);

      /* all same size with black outline */
      immAttr1f(size_id, 2.0f * STRIP_HEIGHT_HALF);
      immAttr4ub(outline_color_id, 0, 0, 0, 255);
      immAttr1u(flags_id, 0);

      y = (float)CHANNEL_FIRST; /* start again at the top */
      for (channel = dopesheet->channels.first; channel; channel = channel->next) {
        float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
        float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);

        /* check if visible */
        if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
            IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
          MovieTrackingTrack *track = channel->track;
          int i;
          bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
          float alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f;

          /* tracked segments */
          for (i = 0; i < channel->tot_segment; i++) {
            int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
                                                                      channel->segments[2 * i]);
            int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
                                                                    channel->segments[2 * i + 1]);

            if (start_frame != end_frame) {
              draw_keyframe_shape(start_frame, y, sel, alpha, pos_id, color_id);
              draw_keyframe_shape(end_frame, y, sel, alpha, pos_id, color_id);
            }
            else {
              draw_keyframe_shape(start_frame, y, sel, alpha, pos_id, color_id);
            }
          }

          /* keyframes */
          i = 0;
          while (i < track->markersnr) {
            MovieTrackingMarker *marker = &track->markers[i];

            if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) {
              int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);

              draw_keyframe_shape(framenr, y, sel, alpha, pos_id, color_id);
            }

            i++;
          }
        }

        /* adjust y-position for next one */
        y -= CHANNEL_STEP;
      }

      immEnd();
      GPU_program_point_size(false);
      immUnbindProgram();
    }

    GPU_blend(false);
  }
}
void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
{
	MovieClip *clip = ED_space_clip_get_clip(sc);
	View2D *v2d = &ar->v2d;

	/* frame range */
	clip_draw_sfra_efra(v2d, scene);

	if (clip) {
		MovieTracking *tracking = &clip->tracking;
		MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
		MovieTrackingDopesheetChannel *channel;
		float y, xscale, yscale;
		float strip[4], selected_strip[4];
		float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);

		/* don't use totrect set, as the width stays the same
		 * (NOTE: this is ok here, the configuration is pretty straightforward)
		 */
		v2d->tot.ymin = (float)(-height);

		y = (float) CHANNEL_FIRST;

		UI_view2d_getscale(v2d, &xscale, &yscale);

		/* setup colors for regular and selected strips */
		UI_GetThemeColor3fv(TH_STRIP, strip);
		UI_GetThemeColor3fv(TH_STRIP_SELECT, selected_strip);

		strip[3] = 0.5f;
		selected_strip[3] = 1.0f;

		glEnable(GL_BLEND);

		clip_draw_dopesheet_background(ar, clip);

		for (channel = dopesheet->channels.first; channel; channel = channel->next) {
			float yminc = (float) (y - CHANNEL_HEIGHT_HALF);
			float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF);

			/* check if visible */
			if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
			    IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax))
			{
				MovieTrackingTrack *track = channel->track;
				float alpha;
				int i, sel = track->flag & TRACK_DOPE_SEL;

				/* selection background */
				if (sel) {
					float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
					float default_color[4] = {0.8f, 0.93f, 0.8f, 0.3f};

					track_channel_color(track, default_color, color);
					glColor4fv(color);

					glRectf(v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF,
					        v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF);
				}

				alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f;

				/* tracked segments */
				for (i = 0; i < channel->tot_segment; i++) {
					int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]);
					int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]);

					if (sel)
						glColor4fv(selected_strip);
					else
						glColor4fv(strip);

					if (start_frame != end_frame) {
						glRectf(start_frame, (float) y - STRIP_HEIGHT_HALF,
						        end_frame, (float) y + STRIP_HEIGHT_HALF);
						draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha);
						draw_keyframe_shape(end_frame, y, xscale, yscale, sel, alpha);
					}
					else {
						draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha);
					}
				}

				/* keyframes */
				i = 0;
				while (i < track->markersnr) {
					MovieTrackingMarker *marker = &track->markers[i];

					if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) {
						int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);

						draw_keyframe_shape(framenr, y, xscale, yscale, sel, alpha);
					}

					i++;
				}
			}

			/* adjust y-position for next one */
			y -= CHANNEL_STEP;
		}

		glDisable(GL_BLEND);
	}

	/* current frame */
	clip_draw_cfra(sc, ar, scene);
}
예제 #9
0
/* Refine marker's position using previously known keyframe.
 * Direction of searching for a keyframe depends on backwards flag,
 * which means if backwards is false, previous keyframe will be as
 * reference.
 */
void BKE_tracking_refine_marker(MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker, bool backwards)
{
	MovieTrackingMarker *reference_marker = NULL;
	ImBuf *reference_ibuf, *destination_ibuf;
	float *search_area, *mask = NULL;
	int frame_width, frame_height;
	int search_area_height, search_area_width;
	int clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS;
	int reference_framenr;
	MovieClipUser user = {0};
	double dst_pixel_x[5], dst_pixel_y[5];
	bool tracked;

	/* Construct a temporary clip used, used to acquire image buffers. */
	user.framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);

	BKE_movieclip_get_size(clip, &user, &frame_width, &frame_height);

	/* Get an image buffer for reference frame, also gets reference marker. */
	if (!refine_marker_reference_frame_get(track,
	                                       marker,
	                                       backwards,
	                                       &reference_framenr))
	{
		return;
	}

	reference_ibuf = tracking_context_get_reference_ibuf(clip, &user, clip_flag, track, reference_framenr,
	                                                     backwards, &reference_marker);
	if (reference_ibuf == NULL) {
		return;
	}

	/* Could not refine with self. */
	if (reference_marker == marker) {
		return;
	}

	/* Destination image buffer has got frame number corresponding to refining marker. */
	destination_ibuf = BKE_movieclip_get_ibuf_flag(clip, &user, clip_flag, MOVIECLIP_CACHE_SKIP);
	if (destination_ibuf == NULL) {
		IMB_freeImBuf(reference_ibuf);
		return;
	}

	/* Get search area from reference image. */
	search_area = track_get_search_floatbuf(reference_ibuf, track, reference_marker,
	                                        &search_area_width, &search_area_height);

	/* If needed, compute track's mask. */
	if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0)
		mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);

	/* Run the tracker from reference frame to current one. */
	tracked = configure_and_run_tracker(destination_ibuf, track, reference_marker, marker,
	                                    search_area, search_area_width, search_area_height,
	                                    mask, dst_pixel_x, dst_pixel_y);

	/* Refine current marker's position if track was successful. */
	if (tracked) {
		tracking_set_marker_coords_from_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y);
		marker->flag |= MARKER_TRACKED;
	}

	/* Free memory used for refining */
	MEM_freeN(search_area);
	if (mask)
		MEM_freeN(mask);
	IMB_freeImBuf(reference_ibuf);
	IMB_freeImBuf(destination_ibuf);
}