void MovieDistortionOperation::initExecution()
{
    this->m_inputOperation = this->getInputSocketReader(0);
    if (this->m_movieClip) {
        MovieClipUser clipUser = {0};
        int calibration_width, calibration_height;

        BKE_movieclip_user_set_frame(&clipUser, this->m_framenumber);
        BKE_movieclip_get_size(this->m_movieClip, &clipUser, &calibration_width, &calibration_height);

        for (unsigned int i = 0; i < s_cache.size(); i++) {
            DistortionCache *c = (DistortionCache *)s_cache[i];
            if (c->isCacheFor(this->m_movieClip, this->m_width, this->m_height,
                              calibration_width, calibration_height, this->m_distortion))
            {
                this->m_cache = c;
                this->m_cache->updateLastUsage();
                return;
            }
        }
        DistortionCache *newC = new DistortionCache(this->m_movieClip, this->m_width, this->m_height,
                calibration_width, calibration_height, this->m_distortion);
        s_cache.push_back(newC);
        this->m_cache = newC;
    }
    else {
        this->m_cache = NULL;
    }
}
Пример #2
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);
		}
	}
}
Пример #3
0
/* checks if image was already loaded, then returns same image
 * otherwise creates new.
 * does not load ibuf itself
 * pass on optional frame for #name images */
MovieClip *BKE_movieclip_file_add(const char *name)
{
    MovieClip *clip;
    MovieClipUser user = {0};
    int file, len, width, height;
    const char *libname;
    char str[FILE_MAX], strtest[FILE_MAX];

    BLI_strncpy(str, name, sizeof(str));
    BLI_path_abs(str, G.main->name);

    /* exists? */
    file = BLI_open(str, O_BINARY | O_RDONLY, 0);
    if (file == -1)
        return NULL;
    close(file);

    /* ** first search an identical clip ** */
    for (clip = G.main->movieclip.first; clip; clip = clip->id.next) {
        BLI_strncpy(strtest, clip->name, sizeof(clip->name));
        BLI_path_abs(strtest, G.main->name);

        if (strcmp(strtest, str) == 0) {
            BLI_strncpy(clip->name, name, sizeof(clip->name));  /* for stringcode */
            clip->id.us++;  /* officially should not, it doesn't link here! */

            return clip;
        }
    }

    /* ** add new movieclip ** */

    /* create a short library name */
    len = strlen(name);

    while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\')
        len--;
    libname = name + len;

    clip = movieclip_alloc(libname);
    BLI_strncpy(clip->name, name, sizeof(clip->name));

    if (BLI_testextensie_array(name, imb_ext_movie))
        clip->source = MCLIP_SRC_MOVIE;
    else
        clip->source = MCLIP_SRC_SEQUENCE;

    user.framenr = 1;
    BKE_movieclip_get_size(clip, &user, &width, &height);
    if (width && height) {
        clip->tracking.camera.principal[0] = ((float)width) / 2.0f;
        clip->tracking.camera.principal[1] = ((float)height) / 2.0f;

        clip->tracking.camera.focal = 24.0f * width / clip->tracking.camera.sensor_width;
    }

    movieclip_calc_length(clip);

    return clip;
}
Пример #4
0
void ED_space_clip_get_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *aspy)
{
	int w, h;

	/* most of tools does not require aspect to be returned with dimensions correction
	 * due to they're invariant to this stuff, but some transformation tools like rotation
	 * should be aware of aspect correction caused by different resolution in different
	 * directions.
	 * mainly this is sued for transformation stuff
	 */

	if (!sc->clip) {
		*aspx = 1.0f;
		*aspy = 1.0f;

		return;
	}

	ED_space_clip_get_aspect(sc, aspx, aspy);
	BKE_movieclip_get_size(sc->clip, &sc->user, &w, &h);

	*aspx *= (float) w;
	*aspy *= (float) h;

	if (*aspx < *aspy) {
		*aspy = *aspy / *aspx;
		*aspx = 1.0f;
	}
	else {
		*aspx = *aspx / *aspy;
		*aspy = 1.0f;
	}
}
Пример #5
0
static void draw_tracks_error_curves(SpaceClip *sc)
{
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	TrackErrorCurveUserData data;

	data.clip = clip;
	data.tracking = tracking;
	data.tracking_object = BKE_tracking_object_get_active(tracking);
	data.active_track = BKE_tracking_track_get_active(tracking);
	data.matrix_initialized = false;
	BKE_movieclip_get_size(clip, &sc->user, &data.width, &data.height);
	data.aspy = 1.0f / tracking->camera.pixel_aspect;

	if (!data.width || !data.height) {
		return;
	}

	clip_graph_tracking_values_iterate(sc,
	                                   (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
	                                   (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
	                                   &data,
	                                   tracking_error_segment_point_cb,
	                                   tracking_error_segment_start_cb,
	                                   tracking_error_segment_end_cb);
}
Пример #6
0
static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
{
	MovieClip *clip= ED_space_clip(sc);
	MovieTracking *tracking= &clip->tracking;
	MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
	int width, height;
	struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata;

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

	if(!width || !height)
		return;

	/* non-selected knot handles */
	userdata.hsize= UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
	userdata.sel= 0;
	userdata.act_track= act_track;
	UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale);
	clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL);

	/* draw graph lines */
	glEnable(GL_BLEND);
	clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb);
	glDisable(GL_BLEND);

	/* selected knot handles on top of curves */
	userdata.sel= 1;
	clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL);
}
Пример #7
0
void ED_space_clip_get_size(SpaceClip *sc, int *width, int *height)
{
	if (sc->clip) {
		BKE_movieclip_get_size(sc->clip, &sc->user, width, height);
	}
	else {
		*width = *height = IMG_SIZE_FALLBACK;
	}
}
Пример #8
0
static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	if (in[0]->data) {
		if (node->id) {
			MovieClip *clip = (MovieClip *)node->id;
			CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA);
			CompBuf *stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
			ImBuf *ibuf;

			ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);

			if (ibuf) {
				RenderData *rd = data;
				ImBuf *obuf;
				MovieTracking *tracking = &clip->tracking;
				int width, height;
				float overscan = 0.0f;
				MovieClipUser user = {0};

				BKE_movieclip_user_set_frame(&user, rd->cfra);

				ibuf->rect_float = cbuf->rect;

				BKE_movieclip_get_size(clip, &user, &width, &height);

				if (!node->storage)
					node->storage = BKE_tracking_distortion_create();

				if (node->custom1 == 0)
					obuf = BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 1);
				else
					obuf = BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 0);

				stackbuf->rect = obuf->rect_float;
				stackbuf->malloc = TRUE;

				obuf->mall &= ~IB_rectfloat;
				obuf->rect_float = NULL;

				IMB_freeImBuf(ibuf);
				IMB_freeImBuf(obuf);
			}

			/* pass on output and free */
			out[0]->data = stackbuf;

			if (cbuf != in[0]->data)
				free_compbuf(cbuf);
		}
		else {
			CompBuf *cbuf = in[0]->data;
			CompBuf *stackbuf = pass_on_compbuf(cbuf);

			out[0]->data = stackbuf;
		}
	}
}
void TrackPositionOperation::initExecution()
{
	MovieTracking *tracking = NULL;
	MovieClipUser user = {0};
	MovieTrackingObject *object;

	zero_v2(this->m_markerPos);
	zero_v2(this->m_relativePos);

	if (!this->m_movieClip)
		return;

	tracking = &this->m_movieClip->tracking;

	BKE_movieclip_user_set_frame(&user, this->m_framenumber);
	BKE_movieclip_get_size(this->m_movieClip, &user, &this->m_width, &this->m_height);

	object = BKE_tracking_object_get_named(tracking, this->m_trackingObjectName);
	if (object) {
		MovieTrackingTrack *track;

		track = BKE_tracking_track_get_named(tracking, object, this->m_trackName);

		if (track) {
			MovieTrackingMarker *marker;
			int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);

			marker = BKE_tracking_marker_get(track, clip_framenr);

			copy_v2_v2(this->m_markerPos, marker->pos);

			if (this->m_position == CMP_TRACKPOS_RELATIVE_START) {
				int i;

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

					if ((marker->flag & MARKER_DISABLED) == 0) {
						copy_v2_v2(this->m_relativePos, marker->pos);

						break;
					}
				}
			}
			else if (this->m_position == CMP_TRACKPOS_RELATIVE_FRAME) {
				int relative_clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip,
				                                                                    this->m_relativeFrame);

				marker = BKE_tracking_marker_get(track, relative_clip_framenr);
				copy_v2_v2(this->m_relativePos, marker->pos);
			}
		}
	}
}
Пример #10
0
/* simple case for movies -- handle frame-by-frame, do threading within single frame */
static void do_movie_proxy(void *pjv, int *UNUSED(build_sizes), int UNUSED(build_count),
                           int *build_undistort_sizes, int build_undistort_count,
                           short *stop, short *do_update, float *progress)
{
	ProxyJob *pj = pjv;
	Scene *scene = pj->scene;
	MovieClip *clip = pj->clip;
	struct MovieDistortion *distortion = NULL;
	int cfra, sfra = SFRA, efra = EFRA;

	if (pj->index_context)
		IMB_anim_index_rebuild(pj->index_context, stop, do_update, progress);

	if (!build_undistort_count) {
		if (*stop)
			pj->stop = 1;

		return;
	}
	else {
		sfra = 1;
		efra = clip->len;
	}

	if (build_undistort_count) {
		int threads = BLI_system_thread_count();
		int width, height;

		BKE_movieclip_get_size(clip, NULL, &width, &height);

		distortion = BKE_tracking_distortion_new(&clip->tracking, width, height);
		BKE_tracking_distortion_set_threads(distortion, threads);
	}

	for (cfra = sfra; cfra <= efra; cfra++) {
		BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra,
		                                build_undistort_sizes, build_undistort_count, 1);

		if (*stop || G.is_break)
			break;

		*do_update = true;
		*progress = ((float) cfra - sfra) / (efra - sfra);
	}

	if (distortion)
		BKE_tracking_distortion_free(distortion);

	if (*stop)
		pj->stop = 1;
}
Пример #11
0
void MovieClipBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
	resolution[0] = 0;
	resolution[1] = 0;

	if (this->m_movieClip) {
		int width, height;

		BKE_movieclip_get_size(this->m_movieClip, this->m_movieClipUser, &width, &height);

		resolution[0] = width;
		resolution[1] = height;
	}
}
Пример #12
0
static void movieclip_load_get_szie(MovieClip *clip)
{
	int width, height;
	MovieClipUser user = {0};

	user.framenr = 1;
	BKE_movieclip_get_size(clip, &user, &width, &height);

	if (width && height) {
		clip->tracking.camera.principal[0] = ((float)width) / 2.0f;
		clip->tracking.camera.principal[1] = ((float)height) / 2.0f;
	}
	else {
		clip->lastsize[0] = clip->lastsize[1] = IMG_SIZE_FALLBACK;
	}
}
void KeyingScreenOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
	resolution[0] = 0;
	resolution[1] = 0;

	if (this->m_movieClip) {
		MovieClipUser user = {0};
		int width, height;
		int clip_frame = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);

		BKE_movieclip_user_set_frame(&user, clip_frame);
		BKE_movieclip_get_size(this->m_movieClip, &user, &width, &height);

		resolution[0] = width;
		resolution[1] = height;
	}
}
void TrackPositionOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler)
{
	MovieClipUser user = {0};
	MovieTracking *tracking = &movieClip->tracking;
	MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, this->trackingObject);
	MovieTrackingTrack *track;
	MovieTrackingMarker *marker;
	int width, height;

	outputValue[0] = 0.0f;

	if (!object)
		return;

	track = BKE_tracking_track_get_named(tracking, object, this->trackName);

	if (!track)
		return;

	BKE_movieclip_user_set_frame(&user, this->framenumber);
	BKE_movieclip_get_size(this->movieClip, &user, &width, &height);

	marker = BKE_tracking_marker_get(track, this->framenumber);

	outputValue[0] = marker->pos[this->axis];

	if (this->relative) {
		int i;

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

			if ((marker->flag & MARKER_DISABLED) == 0) {
				outputValue[0] -= marker->pos[this->axis];

				break;
			}
		}
	}

	if (this->axis == 0)
		outputValue[0] *= width;
	else
		outputValue[0] *= height;
}
void PlaneTrackCommonOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
	NodeOperation::determineResolution(resolution, preferredResolution);

	resolution[0] = 0;
	resolution[1] = 0;

	if (this->m_movieClip) {
		int width, height;
		MovieClipUser user = {0};

		BKE_movieclip_user_set_frame(&user, this->m_framenumber);
		BKE_movieclip_get_size(this->m_movieClip, &user, &width, &height);

		resolution[0] = width;
		resolution[1] = height;
	}
}
Пример #16
0
void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[2])
{
	copy_v2_v2(r_co, co);

	if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
		MovieClip *clip = ED_space_clip_get_clip(sc);
		float aspy = 1.0f / clip->tracking.camera.pixel_aspect;
		int width, height;

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

		r_co[0] *= width;
		r_co[1] *= height * aspy;

		BKE_tracking_undistort_v2(&clip->tracking, r_co, r_co);

		r_co[0] /= width;
		r_co[1] /= height * aspy;
	}
}
static void node_composit_exec_keyingscreen(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
{
	NodeKeyingScreenData *keyingscreen_data = node->storage;
	RenderData *rd = data;
	CompBuf *screenbuf = NULL;

	if (node->id) {
		MovieClip *clip = (MovieClip *) node->id;
		MovieClipUser user = {0};
		int width, height;

		BKE_movieclip_user_set_frame(&user, rd->cfra);
		BKE_movieclip_get_size(clip, &user, &width, &height);

		screenbuf = alloc_compbuf(width, height, CB_RGBA, TRUE);
		compute_gradient_screen(rd, keyingscreen_data, clip, screenbuf);
	}

	out[0]->data = screenbuf;
}
Пример #18
0
static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc)
{
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
	int width, height;
	TrackMotionCurveUserData userdata;

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

	if (!width || !height)
		return;

	/* non-selected knot handles */
	userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
	userdata.sel = false;
	userdata.act_track = act_track;
	UI_view2d_scale_get(v2d, &userdata.xscale, &userdata.yscale);
	clip_graph_tracking_values_iterate(sc,
	                                   (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
	                                   (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
	                                   &userdata, tracking_segment_knot_cb, NULL, NULL);

	/* draw graph lines */
	glEnable(GL_BLEND);
	clip_graph_tracking_values_iterate(sc,
	                                   (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
	                                   (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
	                                   act_track, tracking_segment_point_cb, tracking_segment_start_cb,
	                                   tracking_segment_end_cb);
	glDisable(GL_BLEND);

	/* selected knot handles on top of curves */
	userdata.sel = true;
	clip_graph_tracking_values_iterate(sc,
	                                   (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
	                                   (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
	                                   &userdata, tracking_segment_knot_cb, NULL, NULL);
}
Пример #19
0
void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height)
{
#if 0
	/* originally was needed to support image sequences with different image dimensions,
	 * which might be useful for such things as reconstruction of unordered image sequence,
	 * or painting/rotoscoping of non-equal-sized images, but this ended up in unneeded
	 * cache lookups and even unwanted non-proxied files loading when doing mask parenting,
	 * so let's disable this for now and assume image sequence consists of images with
	 * equal sizes (sergey)
	 */
	if (user->framenr == clip->lastframe) {
#endif
	if (clip->lastsize[0] != 0 && clip->lastsize[1] != 0) {
		*width = clip->lastsize[0];
		*height = clip->lastsize[1];
	}
	else {
		ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);

		if (ibuf && ibuf->x && ibuf->y) {
			real_ibuf_size(clip, user, ibuf, width, height);
		}
		else {
			*width = clip->lastsize[0];
			*height = clip->lastsize[1];
		}

		if (ibuf)
			IMB_freeImBuf(ibuf);
	}
}
void BKE_movieclip_get_size_fl(MovieClip *clip, MovieClipUser *user, float size[2])
{
	int width, height;
	BKE_movieclip_get_size(clip, user, &width, &height);

	size[0] = (float)width;
	size[1] = (float)height;
}
Пример #20
0
static void do_sequence_proxy(void *pjv, int *build_sizes, int build_count,
                              int *build_undistort_sizes, int build_undistort_count,
                              short *stop, short *do_update, float *progress)
{
	ProxyJob *pj = pjv;
	MovieClip *clip = pj->clip;
	Scene *scene = pj->scene;
	int sfra = SFRA, efra = EFRA;
	ProxyThread *handles;
	ListBase threads;
	int i, tot_thread = BLI_system_thread_count();
	ProxyQueue queue;

	BLI_spin_init(&queue.spin);

	queue.cfra = sfra;
	queue.sfra = sfra;
	queue.efra = efra;
	queue.stop = stop;
	queue.do_update = do_update;
	queue.progress = progress;

	handles = MEM_callocN(sizeof(ProxyThread) * tot_thread, "proxy threaded handles");

	if (tot_thread > 1)
		BLI_init_threads(&threads, do_proxy_thread, tot_thread);

	for (i = 0; i < tot_thread; i++) {
		ProxyThread *handle = &handles[i];

		handle->clip = clip;
		handle->queue = &queue;

		handle->build_count = build_count;
		handle->build_sizes = build_sizes;

		handle->build_undistort_count = build_undistort_count;
		handle->build_undistort_sizes = build_undistort_sizes;

		if (build_undistort_count) {
			int width, height;
			BKE_movieclip_get_size(clip, NULL, &width, &height);
			handle->distortion = BKE_tracking_distortion_new(&clip->tracking, width, height);
		}

		if (tot_thread > 1)
			BLI_insert_thread(&threads, handle);
	}

	if (tot_thread > 1)
		BLI_end_threads(&threads);
	else
		do_proxy_thread(handles);

	MEM_freeN(handles);

	if (build_undistort_count) {
		for (i = 0; i < tot_thread; i++) {
			ProxyThread *handle = &handles[i];

			BKE_tracking_distortion_free(handle->distortion);
		}
	}
}
Пример #21
0
void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
{
    if (scopes->ok)
        return;

    if (scopes->track_preview) {
        IMB_freeImBuf(scopes->track_preview);
        scopes->track_preview = NULL;
    }

    scopes->marker = NULL;
    scopes->track = NULL;

    if (clip) {
        MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking);

        if (act_track) {
            MovieTrackingTrack *track = act_track;
            MovieTrackingMarker *marker = BKE_tracking_get_marker(track, user->framenr);

            if (marker->flag & MARKER_DISABLED) {
                scopes->track_disabled = TRUE;
            }
            else {
                ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);

                scopes->track_disabled = FALSE;

                if (ibuf && (ibuf->rect || ibuf->rect_float)) {
                    ImBuf *tmpibuf;
                    MovieTrackingMarker undist_marker = *marker;

                    if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
                        int width, height;
                        float aspy = 1.0f / clip->tracking.camera.pixel_aspect;

                        BKE_movieclip_get_size(clip, user, &width, &height);

                        undist_marker.pos[0] *= width;
                        undist_marker.pos[1] *= height * aspy;

                        BKE_tracking_invert_intrinsics(&clip->tracking, undist_marker.pos, undist_marker.pos);

                        undist_marker.pos[0] /= width;
                        undist_marker.pos[1] /= height * aspy;
                    }

                    /* NOTE: margin should be kept in sync with value from ui_draw_but_TRACKPREVIEW */
                    tmpibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 3 /* margin */,
                              1 /* anchor */, scopes->track_pos, NULL);

                    if (tmpibuf->rect_float)
                        IMB_rect_from_float(tmpibuf);

                    if (tmpibuf->rect)
                        scopes->track_preview = tmpibuf;
                    else
                        IMB_freeImBuf(tmpibuf);
                }

                IMB_freeImBuf(ibuf);
            }

            if ((track->flag & TRACK_LOCKED) == 0) {
                scopes->marker = marker;
                scopes->track = track;
                scopes->slide_scale[0] = track->pat_max[0] - track->pat_min[0];
                scopes->slide_scale[1] = track->pat_max[1] - track->pat_min[1];
            }
        }
    }

    scopes->framenr = user->framenr;
    scopes->ok = TRUE;
}
Пример #22
0
void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *userptr,
                      PointerRNA *trackptr, int compact)
{
	PropertyRNA *prop;
	uiBlock *block;
	uiBut *bt;
	PointerRNA clipptr;
	MovieClip *clip;
	MovieClipUser *user;
	MovieTrackingTrack *track;
	MovieTrackingMarker *marker;
	MarkerUpdateCb *cb;
	const char *tip;
	float pat_min[2], pat_max[2];

	if (!ptr->data)
		return;

	prop = RNA_struct_find_property(ptr, propname);
	if (!prop) {
		printf("%s: property not found: %s.%s\n",
		       __func__, RNA_struct_identifier(ptr->type), propname);
		return;
	}

	if (RNA_property_type(prop) != PROP_POINTER) {
		printf("%s: expected pointer property for %s.%s\n",
		       __func__, RNA_struct_identifier(ptr->type), propname);
		return;
	}

	clipptr = RNA_property_pointer_get(ptr, prop);
	clip = (MovieClip *)clipptr.data;
	user = userptr->data;
	track = trackptr->data;

	marker = BKE_tracking_marker_get(track, user->framenr);

	cb = MEM_callocN(sizeof(MarkerUpdateCb), "uiTemplateMarker update_cb");
	cb->compact = compact;
	cb->clip = clip;
	cb->user = user;
	cb->track = track;
	cb->marker = marker;
	cb->marker_flag = marker->flag;
	cb->framenr = user->framenr;

	if (compact) {
		block = uiLayoutGetBlock(layout);

		if (cb->marker_flag & MARKER_DISABLED)
			tip = "Marker is disabled at current frame";
		else
			tip = "Marker is enabled at current frame";

		bt = uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, 20, 20,
		                      &cb->marker_flag, 0, 0, 1, 0, tip);
		uiButSetNFunc(bt, marker_update_cb, cb, NULL);
	}
	else {
		int width, height, step, digits;
		float pat_dim[2], search_dim[2], search_pos[2];
		uiLayout *col;

		BKE_movieclip_get_size(clip, user, &width, &height);

		if (track->flag & TRACK_LOCKED) {
			uiLayoutSetActive(layout, FALSE);
			block = uiLayoutAbsoluteBlock(layout);
			uiDefBut(block, LABEL, 0, "Track is locked", 0, 0, 300, 19, NULL, 0, 0, 0, 0, "");

			return;
		}

		step = 100;
		digits = 2;

		BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);

		sub_v2_v2v2(pat_dim, pat_max, pat_min);
		sub_v2_v2v2(search_dim, marker->search_max, marker->search_min);

		add_v2_v2v2(search_pos, marker->search_max, marker->search_min);
		mul_v2_fl(search_pos, 0.5);

		to_pixel_space(cb->marker_pos, marker->pos, width, height);
		to_pixel_space(cb->marker_pat, pat_dim, width, height);
		to_pixel_space(cb->marker_search, search_dim, width, height);
		to_pixel_space(cb->marker_search_pos, search_pos, width, height);
		to_pixel_space(cb->track_offset, track->offset, width, height);

		cb->marker_flag = marker->flag;

		block = uiLayoutAbsoluteBlock(layout);
		uiBlockSetHandleFunc(block, marker_block_handler, cb);
		uiBlockSetNFunc(block, marker_update_cb, cb, NULL);

		if (cb->marker_flag & MARKER_DISABLED)
			tip = "Marker is disabled at current frame";
		else
			tip = "Marker is enabled at current frame";

		uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG,  "Enabled", 10, 190, 145, 19, &cb->marker_flag,
		             0, 0, 0, 0, tip);

		col = uiLayoutColumn(layout, TRUE);
		uiLayoutSetActive(col, (cb->marker_flag & MARKER_DISABLED) == 0);

		block = uiLayoutAbsoluteBlock(col);
		uiBlockBeginAlign(block);

		uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, "");
		uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &cb->marker_pos[0],
		          -10 * width, 10.0 * width, step, digits, "X-position of marker at frame in screen coordinates");
		uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &cb->marker_pos[1],
		          -10 * height, 10.0 * height, step, digits, "Y-position of marker at frame in screen coordinates");

		uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, "");
		uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &cb->track_offset[0],
		          -10 * width, 10.0 * width, step, digits, "X-offset to parenting point");
		uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &cb->track_offset[1],
		          -10 * height, 10.0 * height, step, digits, "Y-offset to parenting point");

		uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, "");
		uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f,
		          10.0 * width, step, digits, "Width of marker's pattern in screen coordinates");
		uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f,
		          10.0 * height, step, digits, "Height of marker's pattern in screen coordinates");

		uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, "");
		uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0],
		          -width, width, step, digits, "X-position of search at frame relative to marker's position");
		uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1],
		          -height, height, step, digits, "X-position of search at frame relative to marker's position");
		uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f,
		          10.0 * width, step, digits, "Width of marker's search in screen soordinates");
		uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f,
		          10.0 * height, step, digits, "Height of marker's search in screen soordinates");

		uiBlockEndAlign(block);
	}
}
Пример #23
0
void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
{
	if (scopes->ok)
		return;

	if (scopes->track_preview) {
		IMB_freeImBuf(scopes->track_preview);
		scopes->track_preview = NULL;
	}

	if (scopes->track_search) {
		IMB_freeImBuf(scopes->track_search);
		scopes->track_search = NULL;
	}

	scopes->marker = NULL;
	scopes->track = NULL;
	scopes->track_locked = true;

	if (clip) {
		MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);

		if (act_track) {
			MovieTrackingTrack *track = act_track;
			int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
			MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);

			scopes->marker = marker;
			scopes->track = track;

			if (marker->flag & MARKER_DISABLED) {
				scopes->track_disabled = true;
			}
			else {
				ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);

				scopes->track_disabled = false;

				if (ibuf && (ibuf->rect || ibuf->rect_float)) {
					MovieTrackingMarker undist_marker = *marker;

					if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
						int width, height;
						float aspy = 1.0f / clip->tracking.camera.pixel_aspect;

						BKE_movieclip_get_size(clip, user, &width, &height);

						undist_marker.pos[0] *= width;
						undist_marker.pos[1] *= height * aspy;

						BKE_tracking_undistort_v2(&clip->tracking, undist_marker.pos, undist_marker.pos);

						undist_marker.pos[0] /= width;
						undist_marker.pos[1] /= height * aspy;
					}

					scopes->track_search = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, true, true);

					scopes->undist_marker = undist_marker;

					scopes->frame_width = ibuf->x;
					scopes->frame_height = ibuf->y;

					scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA;
				}

				IMB_freeImBuf(ibuf);
			}

			if ((track->flag & TRACK_LOCKED) == 0) {
				float pat_min[2], pat_max[2];

				scopes->track_locked = false;

				/* XXX: would work fine with non-transformed patterns, but would likely fail
				 *      with transformed patterns, but that would be easier to debug when
				 *      we'll have real pattern sampling (at least to test) */
				BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);

				scopes->slide_scale[0] = pat_max[0] - pat_min[0];
				scopes->slide_scale[1] = pat_max[1] - pat_min[1];
			}
		}
	}

	scopes->framenr = user->framenr;
	scopes->ok = true;
}
Пример #24
0
static void do_sequence_proxy(void *pjv, int *build_sizes, int build_count,
                              int *build_undistort_sizes, int build_undistort_count,
                              short *stop, short *do_update, float *progress)
{
	ProxyJob *pj = pjv;
	MovieClip *clip = pj->clip;
	Scene *scene = pj->scene;
	TaskScheduler *task_scheduler = BLI_task_scheduler_get();
	TaskPool *task_pool;
	int sfra = SFRA, efra = EFRA;
	ProxyThread *handles;
	int i, tot_thread = BLI_task_scheduler_num_threads(task_scheduler);
	int width, height;
	ProxyQueue queue;

	if (build_undistort_count) {
		BKE_movieclip_get_size(clip, NULL, &width, &height);
	}

	BLI_spin_init(&queue.spin);

	queue.cfra = sfra;
	queue.sfra = sfra;
	queue.efra = efra;
	queue.stop = stop;
	queue.do_update = do_update;
	queue.progress = progress;

	task_pool = BLI_task_pool_create(task_scheduler, &queue);
	handles = MEM_callocN(sizeof(ProxyThread) * tot_thread,
	                      "proxy threaded handles");
	for (i = 0; i < tot_thread; i++) {
		ProxyThread *handle = &handles[i];

		handle->clip = clip;

		handle->build_count = build_count;
		handle->build_sizes = build_sizes;

		handle->build_undistort_count = build_undistort_count;
		handle->build_undistort_sizes = build_undistort_sizes;

		if (build_undistort_count) {
			handle->distortion = BKE_tracking_distortion_new(&clip->tracking,
			                                                 width, height);
		}

		BLI_task_pool_push(task_pool,
		                   proxy_task_func,
		                   handle,
		                   false,
		                   TASK_PRIORITY_LOW);
	}

	BLI_task_pool_work_and_wait(task_pool);
	BLI_task_pool_free(task_pool);

	if (build_undistort_count) {
		for (i = 0; i < tot_thread; i++) {
			ProxyThread *handle = &handles[i];
			BKE_tracking_distortion_free(handle->distortion);
		}
	}

	BLI_spin_end(&queue.spin);
	MEM_freeN(handles);
}
Пример #25
0
static void marker_block_handler(bContext *C, void *arg_cb, int event)
{
	MarkerUpdateCb *cb = (MarkerUpdateCb *) arg_cb;
	MovieTrackingMarker *marker;
	int width, height, ok = FALSE;

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

	marker = BKE_tracking_marker_ensure(cb->track, cb->framenr);

	if (event == B_MARKER_POS) {
		marker->pos[0] = cb->marker_pos[0] / width;
		marker->pos[1] = cb->marker_pos[1] / height;

		/* to update position of "parented" objects */
		DAG_id_tag_update(&cb->clip->id, 0);
		WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);

		ok = TRUE;
	}
	else if (event == B_MARKER_PAT_DIM) {
		float dim[2], pat_dim[2], pat_min[2], pat_max[2];
		float scale_x, scale_y;
		int a;

		BKE_tracking_marker_pattern_minmax(cb->marker, pat_min, pat_max);

		sub_v2_v2v2(pat_dim, pat_max, pat_min);

		dim[0] = cb->marker_pat[0] / width;
		dim[1] = cb->marker_pat[1] / height;

		scale_x = dim[0] / pat_dim[0];
		scale_y = dim[1] / pat_dim[1];

		for (a = 0; a < 4; a++) {
			cb->marker->pattern_corners[a][0] *= scale_x;
			cb->marker->pattern_corners[a][1] *= scale_y;
		}

		BKE_tracking_marker_clamp(cb->marker, CLAMP_PAT_DIM);

		ok = TRUE;
	}
	else if (event == B_MARKER_SEARCH_POS) {
		float delta[2], side[2];

		sub_v2_v2v2(side, cb->marker->search_max, cb->marker->search_min);
		mul_v2_fl(side, 0.5f);

		delta[0] = cb->marker_search_pos[0] / width;
		delta[1] = cb->marker_search_pos[1] / height;

		sub_v2_v2v2(cb->marker->search_min, delta, side);
		add_v2_v2v2(cb->marker->search_max, delta, side);

		BKE_tracking_marker_clamp(cb->marker, CLAMP_SEARCH_POS);

		ok = TRUE;
	}
	else if (event == B_MARKER_SEARCH_DIM) {
		float dim[2], search_dim[2];

		sub_v2_v2v2(search_dim, cb->marker->search_max, cb->marker->search_min);

		dim[0] = cb->marker_search[0] / width;
		dim[1] = cb->marker_search[1] / height;

		sub_v2_v2(dim, search_dim);
		mul_v2_fl(dim, 0.5f);

		cb->marker->search_min[0] -= dim[0];
		cb->marker->search_min[1] -= dim[1];

		cb->marker->search_max[0] += dim[0];
		cb->marker->search_max[1] += dim[1];

		BKE_tracking_marker_clamp(cb->marker, CLAMP_SEARCH_DIM);

		ok = TRUE;
	}
	else if (event == B_MARKER_FLAG) {
		marker->flag = cb->marker_flag;

		ok = TRUE;
	}
	else if (event == B_MARKER_OFFSET) {
		float offset[2], delta[2];
		int i;

		offset[0] = cb->track_offset[0] / width;
		offset[1] = cb->track_offset[1] / height;

		sub_v2_v2v2(delta, offset, cb->track->offset);
		copy_v2_v2(cb->track->offset, offset);

		for (i = 0; i < cb->track->markersnr; i++)
			sub_v2_v2(cb->track->markers[i].pos, delta);

		/* to update position of "parented" objects */
		DAG_id_tag_update(&cb->clip->id, 0);
		WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);

		ok = TRUE;
	}

	if (ok)
		WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, cb->clip);
}
Пример #26
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);
}