/* Calculate stabilization data (translation, scale and rotation) from * given median of first and current frame medians, tracking data and * frame number. * * NOTE: frame number should be in clip space, not scene space */ static void stabilization_calculate_data(MovieTracking *tracking, int framenr, int width, int height, float firstmedian[2], float median[2], float translation[2], float *scale, float *angle) { MovieTrackingStabilization *stab = &tracking->stabilization; *scale = (stab->scale - 1.0f) * stab->scaleinf + 1.0f; *angle = 0.0f; translation[0] = (firstmedian[0] - median[0]) * width * (*scale); translation[1] = (firstmedian[1] - median[1]) * height * (*scale); mul_v2_fl(translation, stab->locinf); if ((stab->flag & TRACKING_STABILIZE_ROTATION) && stab->rot_track && stab->rotinf) { MovieTrackingMarker *marker; float a[2], b[2]; float x0 = (float)width / 2.0f, y0 = (float)height / 2.0f; float x = median[0] * width, y = median[1] * height; marker = BKE_tracking_marker_get(stab->rot_track, 1); sub_v2_v2v2(a, marker->pos, firstmedian); a[0] *= width; a[1] *= height; marker = BKE_tracking_marker_get(stab->rot_track, framenr); sub_v2_v2v2(b, marker->pos, median); b[0] *= width; b[1] *= height; *angle = -atan2f(a[0] * b[1] - a[1] * b[0], a[0] * b[0] + a[1] * b[1]); *angle *= stab->rotinf; /* convert to rotation around image center */ translation[0] -= (x0 + (x - x0) * cosf(*angle) - (y - y0) * sinf(*angle) - x) * (*scale); translation[1] -= (y0 + (x - x0) * sinf(*angle) + (y - y0) * cosf(*angle) - y) * (*scale); } }
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; }
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; }
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); }
/* Get image buffer which si used as referece for track. */ static ImBuf *tracking_context_get_reference_ibuf(MovieClip *clip, MovieClipUser *user, int clip_flag, MovieTrackingTrack *track, int curfra, bool backwards, MovieTrackingMarker **reference_marker) { ImBuf *ibuf = NULL; if (track->pattern_match == TRACK_MATCH_KEYFRAME) { ibuf = tracking_context_get_keyframed_ibuf(clip, user, clip_flag, track, curfra, backwards, reference_marker); } else { ibuf = tracking_context_get_frame_ibuf(clip, user, clip_flag, curfra); /* use current marker as keyframed position */ *reference_marker = BKE_tracking_marker_get(track, curfra); } return ibuf; }
/* Get previous keyframed marker. */ MovieTrackingMarker *tracking_get_keyframed_marker(MovieTrackingTrack *track, int current_frame, bool backwards) { MovieTrackingMarker *marker_keyed = NULL; MovieTrackingMarker *marker_keyed_fallback = NULL; int a = BKE_tracking_marker_get(track, current_frame) - track->markers; while (a >= 0 && a < track->markersnr) { int next = backwards ? a + 1 : a - 1; bool is_keyframed = false; MovieTrackingMarker *cur_marker = &track->markers[a]; MovieTrackingMarker *next_marker = NULL; if (next >= 0 && next < track->markersnr) next_marker = &track->markers[next]; if ((cur_marker->flag & MARKER_DISABLED) == 0) { /* If it'll happen so we didn't find a real keyframe marker, * fallback to the first marker in current tracked segment * as a keyframe. */ if (next_marker && next_marker->flag & MARKER_DISABLED) { if (marker_keyed_fallback == NULL) marker_keyed_fallback = cur_marker; } is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0; } if (is_keyframed) { marker_keyed = cur_marker; break; } a = next; } if (marker_keyed == NULL) marker_keyed = marker_keyed_fallback; return marker_keyed; }
static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack *track) { SpaceClip *sc = CTX_wm_space_clip(C); int framenr = ED_space_clip_get_clip_frame_number(sc); MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); float pat_min[2], pat_max[2]; float epsx, epsy; int width, height; ED_space_clip_get_size(sc, &width, &height); BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); epsx = min_ffff(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0], fabsf(pat_min[0]), fabsf(pat_max[0])) / 2; epsy = min_ffff(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1], fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; epsx = max_ff(epsx, 2.0f / width); epsy = max_ff(epsy, 2.0f / height); if (sc->flag & SC_SHOW_MARKER_SEARCH) { if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy)) return TRACK_AREA_SEARCH; } if ((marker->flag & MARKER_DISABLED) == 0) { if (sc->flag & SC_SHOW_MARKER_PATTERN) if (mouse_on_crns(co, marker->pos, marker->pattern_corners, epsx, epsy)) return TRACK_AREA_PAT; epsx = 12.0f / width; epsy = 12.0f / height; if (fabsf(co[0] - marker->pos[0] - track->offset[0]) < epsx && fabsf(co[1] - marker->pos[1] - track->offset[1]) <= epsy) { return TRACK_AREA_POINT; } } return TRACK_AREA_NONE; }
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; }
/* draw grease pencil */ void clip_draw_grease_pencil(bContext *C, int onlyv2d) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); if (!clip) return; if (onlyv2d) { bool is_track_source = sc->gpencil_src == SC_GPENCIL_SRC_TRACK; /* if manual calibration is used then grease pencil data * associated with the clip is already drawn in draw_distortion */ if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || is_track_source) { glPushMatrix(); glMultMatrixf(sc->unistabmat); if (is_track_source) { MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking); if (track) { int framenr = ED_space_clip_get_clip_frame_number(sc); MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); glTranslate2fv(marker->pos); } } ED_gpencil_draw_2dimage(C); glPopMatrix(); } } else { ED_gpencil_draw_view2d(C, 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); } }
static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keyingscreen_data, MovieClip *clip, CompBuf *screenbuf) { MovieClipUser user = {0}; MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; VoronoiTriangulationPoint *triangulated_points; VoronoiSite *sites; ImBuf *ibuf; ListBase *tracksbase; ListBase edges = {NULL, NULL}; int sites_total, triangulated_points_total, triangles_total; int (*triangles)[3]; int i, x, y; float *rect = screenbuf->rect; if (keyingscreen_data->tracking_object[0]) { MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, keyingscreen_data->tracking_object); if (!object) return; tracksbase = BKE_tracking_object_get_tracks(tracking, object); } else tracksbase = BKE_tracking_get_active_tracks(tracking); sites_total = BLI_countlist(tracksbase); if (!sites_total) return; BKE_movieclip_user_set_frame(&user, rd->cfra); ibuf = BKE_movieclip_get_ibuf(clip, &user); sites = MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); track = tracksbase->first; i = 0; while (track) { VoronoiSite *site = &sites[i]; MovieTrackingMarker *marker = BKE_tracking_marker_get(track, rd->cfra); ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); int j; zero_v3(site->color); if (pattern_ibuf) { for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { if (pattern_ibuf->rect_float) { add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); } else { unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect; site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f); site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f); site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f); } } mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y)); IMB_freeImBuf(pattern_ibuf); } site->co[0] = marker->pos[0] * screenbuf->x; site->co[1] = marker->pos[1] * screenbuf->y; track = track->next; i++; } IMB_freeImBuf(ibuf); BLI_voronoi_compute(sites, sites_total, screenbuf->x, screenbuf->y, &edges); BLI_voronoi_triangulate(sites, sites_total, &edges, screenbuf->x, screenbuf->y, &triangulated_points, &triangulated_points_total, &triangles, &triangles_total); for (y = 0; y < screenbuf->y; y++) { for (x = 0; x < screenbuf->x; x++) { int index = 4 * (y * screenbuf->x + x); rect[index + 0] = rect[index + 1] = rect[index + 2] = 0.0f; rect[index + 3] = 1.0f; for (i = 0; i < triangles_total; i++) { int *triangle = triangles[i]; VoronoiTriangulationPoint *a = &triangulated_points[triangle[0]], *b = &triangulated_points[triangle[1]], *c = &triangulated_points[triangle[2]]; float co[2] = {x, y}, w[3]; if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) { if (barycentric_inside_triangle_v2(w)) { rect[index + 0] += a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2]; rect[index + 1] += a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2]; rect[index + 2] += a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2]; } } } } } MEM_freeN(triangulated_points); MEM_freeN(triangles); MEM_freeN(sites); BLI_freelistN(&edges); }
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); }
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; }
KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTriangulation() { MovieClipUser user = {0}; TriangulationData *triangulation; MovieTracking *tracking = &this->m_movieClip->tracking; MovieTrackingTrack *track; VoronoiSite *sites, *site; ImBuf *ibuf; ListBase *tracksbase; ListBase edges = {NULL, NULL}; int sites_total; int i; int width = this->getWidth(); int height = this->getHeight(); int clip_frame = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber); if (this->m_trackingObject[0]) { MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, this->m_trackingObject); if (!object) return NULL; tracksbase = BKE_tracking_object_get_tracks(tracking, object); } else tracksbase = BKE_tracking_get_active_tracks(tracking); /* count sites */ for (track = (MovieTrackingTrack *) tracksbase->first, sites_total = 0; track; track = track->next) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame); float pos[2]; if (marker->flag & MARKER_DISABLED) continue; add_v2_v2v2(pos, marker->pos, track->offset); if (!IN_RANGE_INCL(pos[0], 0.0f, 1.0f) || !IN_RANGE_INCL(pos[1], 0.0f, 1.0f)) { continue; } sites_total++; } if (!sites_total) return NULL; BKE_movieclip_user_set_frame(&user, clip_frame); ibuf = BKE_movieclip_get_ibuf(this->m_movieClip, &user); if (!ibuf) return NULL; triangulation = (TriangulationData *) MEM_callocN(sizeof(TriangulationData), "keying screen triangulation data"); sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); track = (MovieTrackingTrack *) tracksbase->first; for (track = (MovieTrackingTrack *) tracksbase->first, site = sites; track; track = track->next) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame); ImBuf *pattern_ibuf; int j; float pos[2]; if (marker->flag & MARKER_DISABLED) continue; add_v2_v2v2(pos, marker->pos, track->offset); if (!IN_RANGE_INCL(pos[0], 0.0f, 1.0f) || !IN_RANGE_INCL(pos[1], 0.0f, 1.0f)) { continue; } pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); zero_v3(site->color); if (pattern_ibuf) { for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { if (pattern_ibuf->rect_float) { add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); } else { unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect; site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f); site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f); site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f); } } mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y)); IMB_freeImBuf(pattern_ibuf); } site->co[0] = pos[0] * width; site->co[1] = pos[1] * height; site++; } IMB_freeImBuf(ibuf); BLI_voronoi_compute(sites, sites_total, width, height, &edges); BLI_voronoi_triangulate(sites, sites_total, &edges, width, height, &triangulation->triangulated_points, &triangulation->triangulated_points_total, &triangulation->triangles, &triangulation->triangles_total); MEM_freeN(sites); BLI_freelistN(&edges); if (triangulation->triangles_total) { rctf *rect; rect = triangulation->triangles_AABB = (rctf *) MEM_callocN(sizeof(rctf) * triangulation->triangles_total, "voronoi triangulation AABB"); for (i = 0; i < triangulation->triangles_total; i++, rect++) { int *triangle = triangulation->triangles[i]; VoronoiTriangulationPoint *a = &triangulation->triangulated_points[triangle[0]], *b = &triangulation->triangulated_points[triangle[1]], *c = &triangulation->triangulated_points[triangle[2]]; float min[2], max[2]; INIT_MINMAX2(min, max); minmax_v2v2_v2(min, max, a->co); minmax_v2v2_v2(min, max, b->co); minmax_v2v2_v2(min, max, c->co); rect->xmin = min[0]; rect->ymin = min[1]; rect->xmax = max[0]; rect->ymax = max[1]; } } return triangulation; }
/* Draw all kind of tracks. */ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy) { float x, y; MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); MovieTrackingTrack *track, *act_track; MovieTrackingPlaneTrack *plane_track, *active_plane_track; MovieTrackingMarker *marker; int framenr = ED_space_clip_get_clip_frame_number(sc); int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2]; /* ** find window pixel coordinates of origin ** */ /* UI_view2d_view_to_region_no_clip return integer values, this could * lead to 1px flickering when view is locked to selection during playbeck. * to avoid this flickering, calculate base point in the same way as it happens * in UI_view2d_view_to_region_no_clip, but do it in floats here */ UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y); glPushMatrix(); glTranslatef(x, y, 0); glPushMatrix(); glScalef(zoomx, zoomy, 0); glMultMatrixf(sc->stabmat); glScalef(width, height, 0); act_track = BKE_tracking_track_get_active(tracking); /* Draw plane tracks */ active_plane_track = BKE_tracking_plane_track_get_active(tracking); for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) { draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height); } } if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { int count = 0; /* count */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) count++; } track = track->next; } /* undistort */ if (count) { marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos"); track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { ED_clip_point_undistorted_pos(sc, marker->pos, fp); if (track == act_track) active_pos = fp; fp += 2; } } track = track->next; } } } if (sc->flag & SC_SHOW_TRACK_PATH) { track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) draw_track_path(sc, clip, track); track = track->next; } } /* markers outline and non-selected areas */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_outline(sc, track, marker, cur_pos, width, height); draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0); draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height); draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height); if (fp) fp += 2; } } track = track->next; } /* selected areas only, so selection wouldn't be overlapped by * non-selected areas */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { int act = track == act_track; marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (!act) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1); draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height); } if (fp) fp += 2; } } track = track->next; } /* active marker would be displayed on top of everything else */ if (act_track) { if ((act_track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(act_track, framenr); if (MARKER_VISIBLE(sc, act_track, marker)) { copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos); draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1); draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height); } } } if (sc->flag & SC_SHOW_BUNDLES) { MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); float pos[4], vec[4], mat[4][4], aspy; glEnable(GL_POINT_SMOOTH); glPointSize(3.0f); aspy = 1.0f / clip->tracking.camera.pixel_aspect; BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat); track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float npos[2]; copy_v3_v3(vec, track->bundle_pos); vec[3] = 1; mul_v4_m4v4(pos, mat, vec); pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width; pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy; BKE_tracking_distort_v2(tracking, pos, npos); if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) { vec[0] = (marker->pos[0] + track->offset[0]) * width; vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy; sub_v2_v2(vec, npos); if (len_squared_v2(vec) < (3.0f * 3.0f)) glColor3f(0.0f, 1.0f, 0.0f); else glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); if (undistort) glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0); else glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0); glEnd(); } } } track = track->next; } glPointSize(1.0f); glDisable(GL_POINT_SMOOTH); } glPopMatrix(); if (sc->flag & SC_SHOW_NAMES) { /* scaling should be cleared before drawing texts, otherwise font would also be scaled */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { int act = track == act_track; copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy); if (fp) fp += 2; } } track = track->next; } } glPopMatrix(); if (marker_pos) MEM_freeN(marker_pos); }
static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy) { float x, y; const int n = 10; int i, j, a; float pos[2], tpos[2], grid[11][11][2]; MovieTracking *tracking = &clip->tracking; bGPdata *gpd = NULL; float aspy = 1.0f / tracking->camera.pixel_aspect; float dx = (float)width / n, dy = (float)height / n * aspy; float offsx = 0.0f, offsy = 0.0f; if (!tracking->camera.focal) return; if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0) return; UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y); glPushMatrix(); glTranslatef(x, y, 0); glScalef(zoomx, zoomy, 0); glMultMatrixf(sc->stabmat); glScalef(width, height, 0); /* grid */ if (sc->flag & SC_SHOW_GRID) { float val[4][2], idx[4][2]; float min[2], max[2]; for (a = 0; a < 4; a++) { if (a < 2) val[a][a % 2] = FLT_MAX; else val[a][a % 2] = -FLT_MAX; } zero_v2(pos); for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { if (i == 0 || j == 0 || i == n || j == n) { BKE_tracking_distort_v2(tracking, pos, tpos); for (a = 0; a < 4; a++) { int ok; if (a < 2) ok = tpos[a % 2] < val[a][a % 2]; else ok = tpos[a % 2] > val[a][a % 2]; if (ok) { copy_v2_v2(val[a], tpos); idx[a][0] = j; idx[a][1] = i; } } } pos[0] += dx; } pos[0] = 0.0f; pos[1] += dy; } INIT_MINMAX2(min, max); for (a = 0; a < 4; a++) { pos[0] = idx[a][0] * dx; pos[1] = idx[a][1] * dy; BKE_tracking_undistort_v2(tracking, pos, tpos); minmax_v2v2_v2(min, max, tpos); } copy_v2_v2(pos, min); dx = (max[0] - min[0]) / n; dy = (max[1] - min[1]) / n; for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { BKE_tracking_distort_v2(tracking, pos, grid[i][j]); grid[i][j][0] /= width; grid[i][j][1] /= height * aspy; pos[0] += dx; } pos[0] = min[0]; pos[1] += dy; } glColor3f(1.0f, 0.0f, 0.0f); for (i = 0; i <= n; i++) { glBegin(GL_LINE_STRIP); for (j = 0; j <= n; j++) { glVertex2fv(grid[i][j]); } glEnd(); } for (j = 0; j <= n; j++) { glBegin(GL_LINE_STRIP); for (i = 0; i <= n; i++) { glVertex2fv(grid[i][j]); } glEnd(); } } if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking); if (track) { int framenr = ED_space_clip_get_clip_frame_number(sc); MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); offsx = marker->pos[0]; offsy = marker->pos[1]; gpd = track->gpd; } } else { gpd = clip->gpd; } if (sc->flag & SC_MANUAL_CALIBRATION && gpd) { bGPDlayer *layer = gpd->layers.first; while (layer) { bGPDframe *frame = layer->frames.first; if (layer->flag & GP_LAYER_HIDE) { layer = layer->next; continue; } glColor4fv(layer->color); glLineWidth(layer->thickness); glPointSize((float)(layer->thickness + 2)); while (frame) { bGPDstroke *stroke = frame->strokes.first; while (stroke) { if (stroke->flag & GP_STROKE_2DSPACE) { if (stroke->totpoints > 1) { glBegin(GL_LINE_STRIP); for (i = 0; i < stroke->totpoints - 1; i++) { float npos[2], dpos[2], len; int steps; pos[0] = (stroke->points[i].x + offsx) * width; pos[1] = (stroke->points[i].y + offsy) * height * aspy; npos[0] = (stroke->points[i + 1].x + offsx) * width; npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy; len = len_v2v2(pos, npos); steps = ceil(len / 5.0f); /* we want to distort only long straight lines */ if (stroke->totpoints == 2) { BKE_tracking_undistort_v2(tracking, pos, pos); BKE_tracking_undistort_v2(tracking, npos, npos); } sub_v2_v2v2(dpos, npos, pos); mul_v2_fl(dpos, 1.0f / steps); for (j = 0; j <= steps; j++) { BKE_tracking_distort_v2(tracking, pos, tpos); glVertex2f(tpos[0] / width, tpos[1] / (height * aspy)); add_v2_v2(pos, dpos); } } glEnd(); } else if (stroke->totpoints == 1) { glBegin(GL_POINTS); glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy); glEnd(); } } stroke = stroke->next; } frame = frame->next; } layer = layer->next; } glLineWidth(1.0f); glPointSize(1.0f); } glPopMatrix(); }
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; }
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; }
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; }
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 select_groped_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTrackingTrack *track; MovieTrackingMarker *marker; MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); int group = RNA_enum_get(op->ptr, "group"); int framenr = ED_space_clip_get_clip_frame_number(sc); track = tracksbase->first; while (track) { bool ok = false; marker = BKE_tracking_marker_get(track, framenr); if (group == 0) { /* Keyframed */ ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0; } else if (group == 1) { /* Estimated */ ok = marker->framenr != framenr; } else if (group == 2) { /* tracked */ ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED); } else if (group == 3) { /* locked */ ok = track->flag & TRACK_LOCKED; } else if (group == 4) { /* disabled */ ok = marker->flag & MARKER_DISABLED; } else if (group == 5) { /* color */ MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); if (act_track) { ok = (track->flag & TRACK_CUSTOMCOLOR) == (act_track->flag & TRACK_CUSTOMCOLOR); if (ok && track->flag & TRACK_CUSTOMCOLOR) ok = equals_v3v3(track->color, act_track->color); } } else if (group == 6) { /* failed */ ok = (track->flag & TRACK_HAS_BUNDLE) == 0; } if (ok) { track->flag |= SELECT; if (sc->flag & SC_SHOW_MARKER_PATTERN) track->pat_flag |= SELECT; if (sc->flag & SC_SHOW_MARKER_SEARCH) track->search_flag |= SELECT; } track = track->next; } BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); return OPERATOR_FINISHED; }