bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2]) { /* first do outside-bounds check for both points of the segment */ if (s1[0] < rect->xmin && s2[0] < rect->xmin) return false; if (s1[0] > rect->xmax && s2[0] > rect->xmax) return false; if (s1[1] < rect->ymin && s2[1] < rect->ymin) return false; if (s1[1] > rect->ymax && s2[1] > rect->ymax) return false; /* if either points intersect then we definetly intersect */ if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) { return true; } else { /* both points are outside but may insersect the rect */ float tvec1[2]; float tvec2[2]; /* diagonal: [/] */ tvec1[0] = rect->xmin; tvec1[1] = rect->ymin; tvec2[0] = rect->xmin; tvec2[1] = rect->ymax; if (isect_segments_fl(s1, s2, tvec1, tvec2)) { return true; } /* diagonal: [\] */ tvec1[0] = rect->xmin; tvec1[1] = rect->ymax; tvec2[0] = rect->xmax; tvec2[1] = rect->ymin; if (isect_segments_fl(s1, s2, tvec1, tvec2)) { return true; } /* no intersection */ return false; } }
BLI_INLINE unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2]) { BLI_assert(BLI_rctf_isect_pt_v(&layer->bounds, xy)); return ( (unsigned int)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0])) + (((unsigned int)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1])) * layer->buckets_x); }
/** * only called from #ok_bezier_region_circle */ static bool bezier_region_circle_test( const struct KeyframeEdit_CircleData *data_circle, const float xy[2]) { if (BLI_rctf_isect_pt_v(data_circle->rectf_scaled, xy)) { float xy_view[2]; BLI_rctf_transform_pt_v(data_circle->rectf_view, data_circle->rectf_scaled, xy_view, xy); xy_view[0] = xy_view[0] - data_circle->mval[0]; xy_view[1] = xy_view[1] - data_circle->mval[1]; return len_squared_v2(xy_view) < data_circle->radius_squared; } return false; }
/** * only called from #ok_bezier_region_lasso */ static bool bezier_region_lasso_test( const struct KeyframeEdit_LassoData *data_lasso, const float xy[2]) { if (BLI_rctf_isect_pt_v(data_lasso->rectf_scaled, xy)) { float xy_view[2]; BLI_rctf_transform_pt_v(data_lasso->rectf_view, data_lasso->rectf_scaled, xy_view, xy); if (BLI_lasso_is_point_inside(data_lasso->mcords, data_lasso->mcords_tot, xy_view[0], xy_view[1], INT_MAX)) { return true; } } return false; }
float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) { /* can't do this because some layers may invert */ /* if (BLI_rctf_isect_pt_v(&mr_handle->bounds, xy)) */ const unsigned int layers_tot = mr_handle->layers_tot; unsigned int i; MaskRasterLayer *layer = mr_handle->layers; /* return value */ float value = 0.0f; for (i = 0; i < layers_tot; i++, layer++) { float value_layer; /* also used as signal for unused layer (when render is disabled) */ if (layer->alpha != 0.0f && BLI_rctf_isect_pt_v(&layer->bounds, xy)) { value_layer = 1.0f - layer_bucket_depth_from_xy(layer, xy); switch (layer->falloff) { case PROP_SMOOTH: /* ease - gives less hard lines for dilate/erode feather */ value_layer = (3.0f * value_layer * value_layer - 2.0f * value_layer * value_layer * value_layer); break; case PROP_SPHERE: value_layer = sqrtf(2.0f * value_layer - value_layer * value_layer); break; case PROP_ROOT: value_layer = sqrtf(value_layer); break; case PROP_SHARP: value_layer = value_layer * value_layer; break; case PROP_LIN: default: /* nothing */ break; } if (layer->blend != MASK_BLEND_REPLACE) { value_layer *= layer->alpha; } } else { value_layer = 0.0f; } if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { value_layer = 1.0f - value_layer; } switch (layer->blend) { case MASK_BLEND_MERGE_ADD: value += value_layer * (1.0f - value); break; case MASK_BLEND_MERGE_SUBTRACT: value -= value_layer * value; break; case MASK_BLEND_ADD: value += value_layer; break; case MASK_BLEND_SUBTRACT: value -= value_layer; break; case MASK_BLEND_LIGHTEN: value = max_ff(value, value_layer); break; case MASK_BLEND_DARKEN: value = min_ff(value, value_layer); break; case MASK_BLEND_MUL: value *= value_layer; break; case MASK_BLEND_REPLACE: value = (value * (1.0f - layer->alpha)) + (value_layer * layer->alpha); break; case MASK_BLEND_DIFFERENCE: value = fabsf(value - value_layer); break; default: /* same as add */ BLI_assert(0); value += value_layer; break; } /* clamp after applying each layer so we don't get * issues subtracting after accumulating over 1.0f */ CLAMP(value, 0.0f, 1.0f); } return value; }
static int border_select_exec(bContext *C, wmOperator *op) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; int i; rcti rect; rctf rectf; bool changed = false; const bool select = !RNA_boolean_get(op->ptr, "deselect"); const bool extend = RNA_boolean_get(op->ptr, "extend"); /* get rectangle from operator */ WM_operator_properties_border_to_rcti(op, &rect); ED_mask_point_pos(sa, ar, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); ED_mask_point_pos(sa, ar, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); /* do actual selection */ 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) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *point_deform = &points_array[i]; /* TODO: handles? */ /* TODO: uw? */ if (BLI_rctf_isect_pt_v(&rectf, point_deform->bezt.vec[1])) { BKE_mask_point_select_set(point, select); BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, select); } else if (!extend) { BKE_mask_point_select_set(point, false); BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, false); } changed = true; } } } if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }
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; }