static float dist_to_crns(float co[2], float pos[2], float crns[4][2]) { float d1, d2, d3, d4; float p[2] = {co[0] - pos[0], co[1] - pos[1]}; float *v1 = crns[0], *v2 = crns[1]; float *v3 = crns[2], *v4 = crns[3]; d1 = dist_to_line_segment_v2(p, v1, v2); d2 = dist_to_line_segment_v2(p, v2, v3); d3 = dist_to_line_segment_v2(p, v3, v4); d4 = dist_to_line_segment_v2(p, v4, v1); return MIN4(d1, d2, d3, d4); }
static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2]) { float d1, d2, d3, d4; float p[2] = {co[0] - pos[0], co[1] - pos[1]}; float v1[2] = {min[0], min[1]}, v2[2] = {max[0], min[1]}; float v3[2] = {max[0], max[1]}, v4[2] = {min[0], max[1]}; d1 = dist_to_line_segment_v2(p, v1, v2); d2 = dist_to_line_segment_v2(p, v2, v3); d3 = dist_to_line_segment_v2(p, v3, v4); d4 = dist_to_line_segment_v2(p, v4, v1); return MIN4(d1, d2, d3, d4); }
static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val) { MouseSelectUserData *data= userdata; float co[2]= {marker->framenr, val}; if(data->has_prev) { float d= dist_to_line_segment_v2(data->mouse_co, data->prev_co, co); if(data->track==NULL || d<data->min_dist) { data->track= track; data->min_dist= d; data->coord= coord; copy_v2_v2(data->min_co, co); } } data->has_prev= 1; copy_v2_v2(data->prev_co, co); }
bool ED_mask_find_nearest_diff_point(const bContext *C, struct Mask *mask, const float normal_co[2], int threshold, bool feather, MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, float *u_r, float tangent[2], const bool use_deform, const bool use_project) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); MaskLayer *masklay, *point_masklay; MaskSpline *point_spline; MaskSplinePoint *point = NULL; float dist = FLT_MAX, co[2]; int width, height; float u; float scalex, scaley; ED_mask_get_size(sa, &width, &height); ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } for (spline = masklay->splines.first; spline; spline = spline->next) { int i; MaskSplinePoint *cur_point; for (i = 0, cur_point = use_deform ? spline->points_deform : spline->points; i < spline->tot_point; i++, cur_point++) { float *diff_points; unsigned int tot_diff_point; diff_points = BKE_mask_point_segment_diff(spline, cur_point, width, height, &tot_diff_point); if (diff_points) { int j, tot_point; unsigned int tot_feather_point; float *feather_points = NULL, *points; if (feather) { feather_points = BKE_mask_point_segment_feather_diff(spline, cur_point, width, height, &tot_feather_point); points = feather_points; tot_point = tot_feather_point; } else { points = diff_points; tot_point = tot_diff_point; } for (j = 0; j < tot_point - 1; j++) { float cur_dist, a[2], b[2]; a[0] = points[2 * j] * scalex; a[1] = points[2 * j + 1] * scaley; b[0] = points[2 * j + 2] * scalex; b[1] = points[2 * j + 3] * scaley; cur_dist = dist_to_line_segment_v2(co, a, b); if (cur_dist < dist) { if (tangent) sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]); point_masklay = masklay; point_spline = spline; point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point; dist = cur_dist; u = (float)j / tot_point; } } if (feather_points) MEM_freeN(feather_points); MEM_freeN(diff_points); } } } } if (point && dist < threshold) { if (masklay_r) *masklay_r = point_masklay; if (spline_r) *spline_r = point_spline; if (point_r) *point_r = point; if (u_r) { /* TODO(sergey): Projection fails in some weirdo cases.. */ if (use_project) { u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY); } *u_r = u; } return true; } if (masklay_r) *masklay_r = NULL; if (spline_r) *spline_r = NULL; if (point_r) *point_r = NULL; return false; }