Cleanup: Use C++ Array, Span, int2 for lasso coords

This commit is contained in:
Hans Goudey
2024-03-05 11:29:04 -05:00
parent 139607dd26
commit 5993c517bd
27 changed files with 330 additions and 416 deletions

View File

@@ -55,6 +55,9 @@
#include "libmv-capi.h"
#include "tracking_private.h"
using blender::Array;
using blender::int2;
struct MovieDistortion {
libmv_CameraIntrinsics *intrinsics;
/* Parameters needed for coordinates normalization. */
@@ -1115,23 +1118,14 @@ static void track_mask_gpencil_layer_rasterize(const int frame_width,
while (stroke) {
const bGPDspoint *stroke_points = stroke->points;
if (stroke->flag & GP_STROKE_2DSPACE) {
int *mask_points, *point;
point = mask_points = MEM_cnew_array<int>(2 * stroke->totpoints,
"track mask rasterization points");
for (int i = 0; i < stroke->totpoints; i++, point += 2) {
point[0] = stroke_points[i].x * frame_width - region_min[0];
point[1] = stroke_points[i].y * frame_height - region_min[1];
Array<int2> mask_points(stroke->totpoints);
for (const int i : mask_points.index_range()) {
mask_points[i][0] = stroke_points[i].x * frame_width - region_min[0];
mask_points[i][1] = stroke_points[i].y * frame_height - region_min[1];
}
/* TODO: add an option to control whether AA is enabled or not */
BLI_bitmap_draw_2d_poly_v2i_n(0,
0,
mask_width,
mask_height,
(const int(*)[2])mask_points,
stroke->totpoints,
track_mask_set_pixel_cb,
&data);
MEM_freeN(mask_points);
BLI_bitmap_draw_2d_poly_v2i_n(
0, 0, mask_width, mask_height, mask_points, track_mask_set_pixel_cb, &data);
}
stroke = stroke->next;
}

View File

@@ -8,6 +8,9 @@
* \ingroup bli
*/
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
/**
* Plot a line from \a p1 to \a p2 (inclusive).
*
@@ -43,7 +46,6 @@ void BLI_bitmap_draw_2d_poly_v2i_n(int xmin,
int ymin,
int xmax,
int ymax,
const int verts[][2],
int verts_len,
blender::Span<blender::int2> verts,
void (*callback)(int x, int x_end, int y, void *),
void *user_data);

View File

@@ -8,18 +8,18 @@
* \ingroup bli
*/
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
struct rcti;
void BLI_lasso_boundbox(struct rcti *rect, const int mcoords[][2], unsigned int mcoords_len);
bool BLI_lasso_is_point_inside(
const int mcoords[][2], unsigned int mcoords_len, int sx, int sy, int error_value);
void BLI_lasso_boundbox(rcti *rect, blender::Span<blender::int2> mcoords);
bool BLI_lasso_is_point_inside(blender::Span<blender::int2> mcoords,
int sx,
int sy,
int error_value);
/**
* Edge version for lasso select. We assume bound-box check was done.
*/
bool BLI_lasso_is_edge_inside(const int mcoords[][2],
unsigned int mcoords_len,
int x0,
int y0,
int x1,
int y1,
int error_value);
bool BLI_lasso_is_edge_inside(
blender::Span<blender::int2> mcoords, int x0, int y0, int x1, int y1, int error_value);

View File

@@ -20,6 +20,9 @@
#include "BLI_strict_flags.h" /* Keep last. */
using blender::int2;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Draw Line
* \{ */
@@ -317,8 +320,7 @@ void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin,
const int ymin,
const int xmax,
const int ymax,
const int verts[][2],
const int verts_len,
const Span<int2> verts,
void (*callback)(int x, int x_end, int y, void *),
void *user_data)
{
@@ -326,10 +328,10 @@ void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin,
* Optimized by Campbell Barton, 2016 to track sorted intersections. */
int(*span_y)[2] = static_cast<int(*)[2]>(
MEM_mallocN(sizeof(*span_y) * (size_t)verts_len, __func__));
MEM_mallocN(sizeof(*span_y) * (size_t)verts.size(), __func__));
int span_y_len = 0;
for (int i_curr = 0, i_prev = verts_len - 1; i_curr < verts_len; i_prev = i_curr++) {
for (int i_curr = 0, i_prev = int(verts.size() - 1); i_curr < verts.size(); i_prev = i_curr++) {
const int *co_prev = verts[i_prev];
const int *co_curr = verts[i_curr];
@@ -351,14 +353,17 @@ void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin,
}
}
BLI_qsort_r(
span_y, (size_t)span_y_len, sizeof(*span_y), draw_poly_v2i_n__span_y_sort, (void *)verts);
BLI_qsort_r(span_y,
(size_t)span_y_len,
sizeof(*span_y),
draw_poly_v2i_n__span_y_sort,
(void *)verts.data());
struct NodeX {
int span_y_index;
int x;
} *node_x = static_cast<NodeX *>(
MEM_mallocN(sizeof(*node_x) * (size_t)(verts_len + 1), __func__));
MEM_mallocN(sizeof(*node_x) * (size_t)(verts.size() + 1), __func__));
int node_x_len = 0;
int span_y_index = 0;

View File

@@ -15,14 +15,15 @@
#include "BLI_strict_flags.h" /* Keep last. */
void BLI_lasso_boundbox(rcti *rect, const int mcoords[][2], const uint mcoords_len)
{
uint a;
using blender::int2;
using blender::Span;
void BLI_lasso_boundbox(rcti *rect, const Span<int2> mcoords)
{
rect->xmin = rect->xmax = mcoords[0][0];
rect->ymin = rect->ymax = mcoords[0][1];
for (a = 1; a < mcoords_len; a++) {
for (const int64_t a : mcoords.index_range().drop_front(1)) {
if (mcoords[a][0] < rect->xmin) {
rect->xmin = mcoords[a][0];
}
@@ -38,50 +39,45 @@ void BLI_lasso_boundbox(rcti *rect, const int mcoords[][2], const uint mcoords_l
}
}
bool BLI_lasso_is_point_inside(const int mcoords[][2],
const uint mcoords_len,
bool BLI_lasso_is_point_inside(const Span<int2> mcoords,
const int sx,
const int sy,
const int error_value)
{
if (sx == error_value || mcoords_len == 0) {
if (sx == error_value || mcoords.is_empty()) {
return false;
}
const int pt[2] = {sx, sy};
return isect_point_poly_v2_int(pt, mcoords, mcoords_len);
return isect_point_poly_v2_int(
pt, reinterpret_cast<const int(*)[2]>(mcoords.data()), uint(mcoords.size()));
}
bool BLI_lasso_is_edge_inside(const int mcoords[][2],
const uint mcoords_len,
int x0,
int y0,
int x1,
int y1,
const int error_value)
bool BLI_lasso_is_edge_inside(
const Span<int2> mcoords, int x0, int y0, int x1, int y1, const int error_value)
{
if (x0 == error_value || x1 == error_value || mcoords_len == 0) {
if (x0 == error_value || x1 == error_value || mcoords.is_empty()) {
return false;
}
const int v1[2] = {x0, y0}, v2[2] = {x1, y1};
/* check points in lasso */
if (BLI_lasso_is_point_inside(mcoords, mcoords_len, v1[0], v1[1], error_value)) {
if (BLI_lasso_is_point_inside(mcoords, v1[0], v1[1], error_value)) {
return true;
}
if (BLI_lasso_is_point_inside(mcoords, mcoords_len, v2[0], v2[1], error_value)) {
if (BLI_lasso_is_point_inside(mcoords, v2[0], v2[1], error_value)) {
return true;
}
/* no points in lasso, so we have to intersect with lasso edge */
if (isect_seg_seg_v2_int(mcoords[0], mcoords[mcoords_len - 1], v1, v2) > 0) {
if (isect_seg_seg_v2_int(mcoords[0], mcoords.last(), v1, v2) > 0) {
return true;
}
for (uint a = 0; a < mcoords_len - 1; a++) {
if (isect_seg_seg_v2_int(mcoords[a], mcoords[a + 1], v1, v2) > 0) {
for (const int64_t i : mcoords.index_range().drop_back(1)) {
if (isect_seg_seg_v2_int(mcoords[i], mcoords[i + 1], v1, v2) > 0) {
return true;
}
}

View File

@@ -11,6 +11,7 @@
#include "DNA_ID.h"
#include "BLI_array.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_sys_types.h" /* for bool and uint */
struct ARegion;
@@ -103,8 +104,7 @@ uint *DRW_select_buffer_bitmap_from_circle(Depsgraph *depsgraph,
uint *DRW_select_buffer_bitmap_from_poly(Depsgraph *depsgraph,
ARegion *region,
View3D *v3d,
const int poly[][2],
int face_len,
blender::Span<blender::int2> poly,
const rcti *rect,
uint *r_bitmap_len);
/**

View File

@@ -29,6 +29,9 @@
#include "../engines/select/select_engine.hh"
using blender::int2;
using blender::Span;
bool SELECTID_Context::is_dirty(RegionView3D *rv3d)
{
/* Check if the viewport has changed. */
@@ -229,8 +232,7 @@ static void drw_select_mask_px_cb(int x, int x_end, int y, void *user_data)
uint *DRW_select_buffer_bitmap_from_poly(Depsgraph *depsgraph,
ARegion *region,
View3D *v3d,
const int poly[][2],
const int face_len,
const Span<int2> poly,
const rcti *rect,
uint *r_bitmap_len)
{
@@ -257,7 +259,6 @@ uint *DRW_select_buffer_bitmap_from_poly(Depsgraph *depsgraph,
rect_px.xmax,
rect_px.ymax,
poly,
face_len,
drw_select_mask_px_cb,
&poly_mask_data);

View File

@@ -596,9 +596,7 @@ bool keyframe_region_lasso_test(const KeyframeEdit_LassoData *data_lasso, const
BLI_rctf_transform_pt_v(data_lasso->rectf_view, data_lasso->rectf_scaled, xy_view, xy);
if (BLI_lasso_is_point_inside(
data_lasso->mcoords, data_lasso->mcoords_len, xy_view[0], xy_view[1], INT_MAX))
{
if (BLI_lasso_is_point_inside(data_lasso->mcoords, xy_view[0], xy_view[1], INT_MAX)) {
return true;
}
}

View File

@@ -764,8 +764,7 @@ bool select_lasso(const ViewContext &vc,
const eSelectOp sel_op)
{
rcti bbox;
const int(*coord_array)[2] = reinterpret_cast<const int(*)[2]>(lasso_coords.data());
BLI_lasso_boundbox(&bbox, coord_array, lasso_coords.size());
BLI_lasso_boundbox(&bbox, lasso_coords);
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
@@ -783,8 +782,7 @@ bool select_lasso(const ViewContext &vc,
vc.region, positions[point_i], projection_matrix);
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(
coord_array, lasso_coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED))
BLI_lasso_is_point_inside(lasso_coords, int(pos_proj.x), int(pos_proj.y), IS_CLIPPED))
{
apply_selection_operation_at_index(selection.span, point_i, sel_op);
changed = true;
@@ -799,8 +797,7 @@ bool select_lasso(const ViewContext &vc,
vc.region, positions[points.first()], projection_matrix);
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(
coord_array, lasso_coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED))
BLI_lasso_is_point_inside(lasso_coords, int(pos_proj.x), int(pos_proj.y), IS_CLIPPED))
{
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
@@ -816,8 +813,7 @@ bool select_lasso(const ViewContext &vc,
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_segment(&bbox, int2(pos1_proj), int2(pos2_proj)) &&
BLI_lasso_is_edge_inside(coord_array,
lasso_coords.size(),
BLI_lasso_is_edge_inside(lasso_coords,
int(pos1_proj.x),
int(pos1_proj.y),
int(pos2_proj.x),

View File

@@ -5482,8 +5482,7 @@ void GPENCIL_OT_stroke_smooth(wmOperatorType *ot)
/* smart stroke cutter for trimming stroke ends */
struct GP_SelectLassoUserData {
rcti rect;
const int (*mcoords)[2];
int mcoords_len;
blender::Array<blender::int2> mcoords;
};
static bool gpencil_test_lasso(bGPDstroke *gps,
@@ -5499,7 +5498,7 @@ static bool gpencil_test_lasso(bGPDstroke *gps,
gpencil_point_to_xy(gsc, gps, &pt2, &x0, &y0);
/* test if in lasso */
return (!ELEM(V2D_IS_CLIPPED, x0, y0) && BLI_rcti_isect_pt(&data->rect, x0, y0) &&
BLI_lasso_is_point_inside(data->mcoords, data->mcoords_len, x0, y0, INT_MAX));
BLI_lasso_is_point_inside(data->mcoords, x0, y0, INT_MAX));
}
typedef bool (*GPencilTestFn)(bGPDstroke *gps,
@@ -5741,20 +5740,16 @@ static int gpencil_cutter_exec(bContext *C, wmOperator *op)
}
GP_SelectLassoUserData data{};
data.mcoords = WM_gesture_lasso_path_to_array(C, op, &data.mcoords_len);
/* Sanity check. */
if (data.mcoords == nullptr) {
data.mcoords = WM_gesture_lasso_path_to_array(C, op);
if (data.mcoords.is_empty()) {
return OPERATOR_PASS_THROUGH;
}
/* Compute boundbox of lasso (for faster testing later). */
BLI_lasso_boundbox(&data.rect, data.mcoords, data.mcoords_len);
BLI_lasso_boundbox(&data.rect, data.mcoords);
gpencil_cutter_lasso_select(C, op, gpencil_test_lasso, &data);
MEM_freeN((void *)data.mcoords);
return OPERATOR_FINISHED;
}

View File

@@ -1807,8 +1807,7 @@ struct GP_SelectUserData {
int mx, my, radius;
/* Bounding box rect */
rcti rect;
const int (*lasso_coords)[2];
int lasso_coords_len;
blender::Array<blender::int2> lasso_coords;
};
typedef bool (*GPencilTestFn)(ARegion *region,
@@ -2296,30 +2295,25 @@ static bool gpencil_test_lasso(ARegion *region,
if (gpencil_3d_point_to_screen_space(region, diff_mat, pt, co)) {
/* test if in lasso boundbox + within the lasso noose */
return (BLI_rcti_isect_pt(&user_data->rect, co[0], co[1]) &&
BLI_lasso_is_point_inside(
user_data->lasso_coords, user_data->lasso_coords_len, co[0], co[1], INT_MAX));
BLI_lasso_is_point_inside(user_data->lasso_coords, co[0], co[1], INT_MAX));
}
return false;
}
static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
{
GP_SelectUserData data = {0};
data.lasso_coords = WM_gesture_lasso_path_to_array(C, op, &data.lasso_coords_len);
/* Sanity check. */
if (data.lasso_coords == nullptr) {
GP_SelectUserData data{};
data.lasso_coords = WM_gesture_lasso_path_to_array(C, op);
if (data.lasso_coords.is_empty()) {
return OPERATOR_PASS_THROUGH;
}
/* Compute boundbox of lasso (for faster testing later). */
BLI_lasso_boundbox(&data.rect, data.lasso_coords, data.lasso_coords_len);
BLI_lasso_boundbox(&data.rect, data.lasso_coords);
rcti rect = data.rect;
int ret = gpencil_generic_select_exec(C, op, gpencil_test_lasso, rect, &data);
MEM_freeN((void *)data.lasso_coords);
return ret;
}

View File

@@ -3093,9 +3093,8 @@ bool ED_gpencil_stroke_point_is_inside(const bGPDstroke *gps,
return hit;
}
int(*mcoords)[2] = nullptr;
int len = gps->totpoints;
mcoords = static_cast<int(*)[2]>(MEM_mallocN(sizeof(int[2]) * len, __func__));
blender::Array<blender::int2> mcoords(len);
/* Convert stroke to 2D array of points. */
const bGPDspoint *pt;
@@ -3108,14 +3107,11 @@ bool ED_gpencil_stroke_point_is_inside(const bGPDstroke *gps,
/* Compute bound-box of lasso (for faster testing later). */
rcti rect;
BLI_lasso_boundbox(&rect, mcoords, len);
BLI_lasso_boundbox(&rect, mcoords);
/* Test if point inside stroke. */
hit = (!ELEM(V2D_IS_CLIPPED, mval[0], mval[1]) && BLI_rcti_isect_pt(&rect, mval[0], mval[1]) &&
BLI_lasso_is_point_inside(mcoords, len, mval[0], mval[1], INT_MAX));
/* Free memory. */
MEM_SAFE_FREE(mcoords);
BLI_lasso_is_point_inside(mcoords, mval[0], mval[1], INT_MAX));
return hit;
}

View File

@@ -8,7 +8,9 @@
#pragma once
#include "BLI_array.hh"
#include "BLI_math_vector_types.hh"
#include "ED_anim_api.hh" /* for enum eAnimFilter_Flags */
struct BezTriple;
@@ -98,8 +100,7 @@ enum eEditKeyframes_Mirror {
struct KeyframeEdit_LassoData {
rctf *rectf_scaled;
const rctf *rectf_view;
const int (*mcoords)[2];
int mcoords_len;
blender::Array<blender::int2> mcoords;
};
/* use with BEZT_OK_REGION_CIRCLE */

View File

@@ -11,6 +11,7 @@
#include "BLI_lasso_2d.hh"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_vector_types.hh"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
@@ -34,6 +35,10 @@
#include "mask_intern.h" /* own include */
using blender::Array;
using blender::int2;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Public Mask Selection API
* \{ */
@@ -522,10 +527,7 @@ void MASK_OT_select_box(wmOperatorType *ot)
/** \name Lasso Select Operator
* \{ */
static bool do_lasso_select_mask(bContext *C,
const int mcoords[][2],
const int mcoords_len,
const eSelectOp sel_op)
static bool do_lasso_select_mask(bContext *C, const Span<int2> mcoords, const eSelectOp sel_op)
{
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
@@ -544,7 +546,7 @@ static bool do_lasso_select_mask(bContext *C,
}
/* get rectangle from operator */
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
/* do actual selection */
for (MaskLayer *mask_layer_orig = static_cast<MaskLayer *>(mask_orig->masklayers.first),
@@ -585,7 +587,7 @@ static bool do_lasso_select_mask(bContext *C,
&screen_co[1]);
if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
BLI_lasso_is_point_inside(mcoords, mcoords_len, screen_co[0], screen_co[1], INT_MAX))
BLI_lasso_is_point_inside(mcoords, screen_co[0], screen_co[1], INT_MAX))
{
BKE_mask_point_select_set(point, select);
BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, select);
@@ -607,18 +609,15 @@ static bool do_lasso_select_mask(bContext *C,
static int clip_lasso_select_exec(bContext *C, wmOperator *op)
{
int mcoords_len;
const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
if (mcoords) {
const eSelectOp sel_op = eSelectOp(RNA_enum_get(op->ptr, "mode"));
do_lasso_select_mask(C, mcoords, mcoords_len, sel_op);
MEM_freeN((void *)mcoords);
return OPERATOR_FINISHED;
const Array<int2> mcoords = WM_gesture_lasso_path_to_array(C, op);
if (mcoords.is_empty()) {
return OPERATOR_PASS_THROUGH;
}
return OPERATOR_PASS_THROUGH;
const eSelectOp sel_op = eSelectOp(RNA_enum_get(op->ptr, "mode"));
do_lasso_select_mask(C, mcoords, sel_op);
return OPERATOR_FINISHED;
}
void MASK_OT_select_lasso(wmOperatorType *ot)

View File

@@ -2447,7 +2447,10 @@ int PE_lasso_select(bContext *C, const int mcoords[][2], const int mcoords_len,
((ED_view3d_project_int_global(region, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) ==
V3D_PROJ_RET_OK) &&
BLI_lasso_is_point_inside(
mcoords, mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED) &&
{reinterpret_cast<const blender::int2 *>(mcoords), mcoords_len},
screen_co[0],
screen_co[1],
IS_CLIPPED) &&
key_test_depth(&data, co, screen_co));
const int sel_op_result = ED_select_op_action_deselected(
eSelectOp(sel_op), is_select, is_inside);
@@ -2468,7 +2471,10 @@ int PE_lasso_select(bContext *C, const int mcoords[][2], const int mcoords_len,
((ED_view3d_project_int_global(region, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) ==
V3D_PROJ_RET_OK) &&
BLI_lasso_is_point_inside(
mcoords, mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED) &&
{reinterpret_cast<const blender::int2 *>(mcoords), mcoords_len},
screen_co[0],
screen_co[1],
IS_CLIPPED) &&
key_test_depth(&data, co, screen_co));
const int sel_op_result = ED_select_op_action_deselected(
eSelectOp(sel_op), is_select, is_inside);

View File

@@ -1035,12 +1035,11 @@ static void sculpt_gesture_trim_geometry_generate(gesture::GestureData *gesture_
ViewContext *vc = &gesture_data->vc;
ARegion *region = vc->region;
const int tot_screen_points = gesture_data->tot_gesture_points;
BLI_assert(tot_screen_points > 1);
float(*screen_points)[2] = gesture_data->gesture_points;
const Span<float2> screen_points = gesture_data->gesture_points;
BLI_assert(screen_points.size() > 1);
const int trim_totverts = tot_screen_points * 2;
const int trim_faces_nums = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points);
const int trim_totverts = screen_points.size() * 2;
const int trim_faces_nums = (2 * (screen_points.size() - 2)) + (2 * screen_points.size());
trim_operation->mesh = BKE_mesh_new_nomain(
trim_totverts, 0, trim_faces_nums, trim_faces_nums * 3);
trim_operation->true_mesh_co = static_cast<float(*)[3]>(
@@ -1084,7 +1083,7 @@ static void sculpt_gesture_trim_geometry_generate(gesture::GestureData *gesture_
madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_front);
}
for (int i = 0; i < tot_screen_points; i++) {
for (const int i : screen_points.index_range()) {
float new_point[3];
if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
@@ -1104,7 +1103,7 @@ static void sculpt_gesture_trim_geometry_generate(gesture::GestureData *gesture_
/* Write vertices coordinates for the back face. */
madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_back);
for (int i = 0; i < tot_screen_points; i++) {
for (const int i : screen_points.index_range()) {
float new_point[3];
if (trim_operation->extrude_mode == SCULPT_GESTURE_TRIM_EXTRUDE_PROJECT) {
@@ -1123,11 +1122,11 @@ static void sculpt_gesture_trim_geometry_generate(gesture::GestureData *gesture_
madd_v3_v3fl(new_point, shape_normal, depth_back - dist);
}
copy_v3_v3(positions[i + tot_screen_points], new_point);
copy_v3_v3(positions[i + screen_points.size()], new_point);
}
/* Project to object space. */
for (int i = 0; i < tot_screen_points * 2; i++) {
for (int i = 0; i < screen_points.size() * 2; i++) {
float new_point[3];
copy_v3_v3(new_point, positions[i]);
@@ -1136,10 +1135,11 @@ static void sculpt_gesture_trim_geometry_generate(gesture::GestureData *gesture_
}
/* Get the triangulation for the front/back poly. */
const int tot_tris_face = tot_screen_points - 2;
const int tot_tris_face = screen_points.size() - 2;
uint(*r_tris)[3] = static_cast<uint(*)[3]>(
MEM_malloc_arrayN(tot_tris_face, sizeof(uint[3]), "tris"));
BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris);
BLI_polyfill_calc(
reinterpret_cast<const float(*)[2]>(screen_points.data()), screen_points.size(), 0, r_tris);
/* Write the front face triangle indices. */
MutableSpan<int> face_offsets = trim_operation->mesh->face_offsets_for_write();
@@ -1158,9 +1158,9 @@ static void sculpt_gesture_trim_geometry_generate(gesture::GestureData *gesture_
/* Write the back face triangle indices. */
for (int i = 0; i < tot_tris_face; i++) {
face_offsets[face_index] = loop_index;
corner_verts[loop_index + 0] = r_tris[i][0] + tot_screen_points;
corner_verts[loop_index + 1] = r_tris[i][1] + tot_screen_points;
corner_verts[loop_index + 2] = r_tris[i][2] + tot_screen_points;
corner_verts[loop_index + 0] = r_tris[i][0] + screen_points.size();
corner_verts[loop_index + 1] = r_tris[i][1] + screen_points.size();
corner_verts[loop_index + 2] = r_tris[i][2] + screen_points.size();
face_index++;
loop_index += 3;
}
@@ -1168,30 +1168,30 @@ static void sculpt_gesture_trim_geometry_generate(gesture::GestureData *gesture_
MEM_freeN(r_tris);
/* Write the indices for the lateral triangles. */
for (int i = 0; i < tot_screen_points; i++) {
for (const int i : screen_points.index_range()) {
face_offsets[face_index] = loop_index;
int current_index = i;
int next_index = current_index + 1;
if (next_index >= tot_screen_points) {
if (next_index >= screen_points.size()) {
next_index = 0;
}
corner_verts[loop_index + 0] = next_index + tot_screen_points;
corner_verts[loop_index + 0] = next_index + screen_points.size();
corner_verts[loop_index + 1] = next_index;
corner_verts[loop_index + 2] = current_index;
face_index++;
loop_index += 3;
}
for (int i = 0; i < tot_screen_points; i++) {
for (const int i : screen_points.index_range()) {
face_offsets[face_index] = loop_index;
int current_index = i;
int next_index = current_index + 1;
if (next_index >= tot_screen_points) {
if (next_index >= screen_points.size()) {
next_index = 0;
}
corner_verts[loop_index + 0] = current_index;
corner_verts[loop_index + 1] = current_index + tot_screen_points;
corner_verts[loop_index + 2] = next_index + tot_screen_points;
corner_verts[loop_index + 1] = current_index + screen_points.size();
corner_verts[loop_index + 2] = next_index + screen_points.size();
face_index++;
loop_index += 3;
}

View File

@@ -97,22 +97,14 @@ GestureData *init_from_lasso(bContext *C, wmOperator *op)
init_common(C, op, gesture_data);
int mcoords_len;
const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
if (!mcoords) {
return nullptr;
}
/* A single point is equally as invalid for a lasso gesture as no points. */
if (mcoords_len == 1) {
MEM_freeN((void *)mcoords);
const Array<int2> mcoords = WM_gesture_lasso_path_to_array(C, op);
if (mcoords.size() <= 1) {
return nullptr;
}
gesture_data->lasso.projviewobjmat = ED_view3d_ob_project_mat_get(gesture_data->vc.rv3d,
gesture_data->vc.obact);
BLI_lasso_boundbox(&gesture_data->lasso.boundbox, mcoords, mcoords_len);
BLI_lasso_boundbox(&gesture_data->lasso.boundbox, mcoords);
const int lasso_width = 1 + gesture_data->lasso.boundbox.xmax -
gesture_data->lasso.boundbox.xmin;
const int lasso_height = 1 + gesture_data->lasso.boundbox.ymax -
@@ -125,7 +117,6 @@ GestureData *init_from_lasso(bContext *C, wmOperator *op)
gesture_data->lasso.boundbox.xmax,
gesture_data->lasso.boundbox.ymax,
mcoords,
mcoords_len,
lasso_px_cb,
gesture_data);
@@ -136,16 +127,12 @@ GestureData *init_from_lasso(bContext *C, wmOperator *op)
gesture_data->vc.obact,
&gesture_data->lasso.boundbox);
gesture_data->gesture_points = static_cast<float(*)[2]>(
MEM_malloc_arrayN(mcoords_len, sizeof(float[2]), "trim points"));
gesture_data->tot_gesture_points = mcoords_len;
for (int i = 0; i < mcoords_len; i++) {
gesture_data->gesture_points.reinitialize(mcoords.size());
for (const int i : mcoords.index_range()) {
gesture_data->gesture_points[i][0] = mcoords[i][0];
gesture_data->gesture_points[i][1] = mcoords[i][1];
}
MEM_freeN((void *)mcoords);
return gesture_data;
}
@@ -163,9 +150,7 @@ GestureData *init_from_box(bContext *C, wmOperator *op)
ED_view3d_clipping_calc(
&bb, gesture_data->true_clip_planes, gesture_data->vc.region, gesture_data->vc.obact, &rect);
gesture_data->gesture_points = static_cast<float(*)[2]>(
MEM_calloc_arrayN(4, sizeof(float[2]), "trim points"));
gesture_data->tot_gesture_points = 4;
gesture_data->gesture_points.reinitialize(4);
gesture_data->gesture_points[0][0] = rect.xmax;
gesture_data->gesture_points[0][1] = rect.ymax;
@@ -285,7 +270,6 @@ GestureData *init_from_line(bContext *C, wmOperator *op)
void free_data(GestureData *gesture_data)
{
MEM_SAFE_FREE(gesture_data->gesture_points);
MEM_SAFE_FREE(gesture_data->operation);
MEM_delete(gesture_data);
}

View File

@@ -1714,8 +1714,7 @@ struct GestureData {
/* Gesture data. */
/* Screen space points that represent the gesture shape. */
float (*gesture_points)[2];
int tot_gesture_points;
Array<float2> gesture_points;
/* View parameters. */
float3 true_view_normal;

View File

@@ -902,8 +902,8 @@ static int actkeys_lassoselect_exec(bContext *C, wmOperator *op)
}
data_lasso.rectf_view = &rect_fl;
data_lasso.mcoords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcoords_len);
if (data_lasso.mcoords == nullptr) {
data_lasso.mcoords = WM_gesture_lasso_path_to_array(C, op);
if (data_lasso.mcoords.is_empty()) {
return OPERATOR_CANCELLED;
}
@@ -914,14 +914,12 @@ static int actkeys_lassoselect_exec(bContext *C, wmOperator *op)
}
/* get settings from operator */
BLI_lasso_boundbox(&rect, data_lasso.mcoords, data_lasso.mcoords_len);
BLI_lasso_boundbox(&rect, data_lasso.mcoords);
BLI_rctf_rcti_copy(&rect_fl, &rect);
/* apply box_select action */
region_select_action_keys(&ac, &rect_fl, BEZT_OK_CHANNEL_LASSO, selectmode, &data_lasso);
MEM_freeN((void *)data_lasso.mcoords);
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, nullptr);
if (ANIM_animdata_can_have_greasepencil(eAnimCont_Types(ac.datatype))) {

View File

@@ -15,6 +15,7 @@
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
#include "BLI_math_vector.h"
#include "BLI_math_vector_types.hh"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
@@ -37,6 +38,10 @@
#include "clip_intern.h" /* own include */
#include "tracking_ops_intern.h" /* own include */
using blender::Array;
using blender::int2;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Point track marker picking.
* \{ */
@@ -835,10 +840,7 @@ void CLIP_OT_select_box(wmOperatorType *ot)
/********************** lasso select operator *********************/
static int do_lasso_select_marker(bContext *C,
const int mcoords[][2],
const int mcoords_len,
bool select)
static int do_lasso_select_marker(bContext *C, const Span<int2> mcoords, bool select)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *region = CTX_wm_region(C);
@@ -850,7 +852,7 @@ static int do_lasso_select_marker(bContext *C,
const int framenr = ED_space_clip_get_clip_frame_number(sc);
/* get rectangle from operator */
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
/* do actual selection */
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
@@ -867,8 +869,7 @@ static int do_lasso_select_marker(bContext *C,
ED_clip_point_stable_pos__reverse(sc, region, marker->pos, screen_co);
if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
BLI_lasso_is_point_inside(
mcoords, mcoords_len, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
BLI_lasso_is_point_inside(mcoords, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
{
if (select) {
BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT);
@@ -897,8 +898,7 @@ static int do_lasso_select_marker(bContext *C,
ED_clip_point_stable_pos__reverse(sc, region, plane_marker->corners[i], screen_co);
if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
BLI_lasso_is_point_inside(
mcoords, mcoords_len, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
BLI_lasso_is_point_inside(mcoords, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
{
if (select) {
plane_track->flag |= SELECT;
@@ -924,24 +924,22 @@ static int do_lasso_select_marker(bContext *C,
static int clip_lasso_select_exec(bContext *C, wmOperator *op)
{
int mcoords_len;
const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
const Array<int2> mcoords = WM_gesture_lasso_path_to_array(C, op);
if (mcoords) {
const eSelectOp sel_op = eSelectOp(RNA_enum_get(op->ptr, "mode"));
const bool select = (sel_op != SEL_OP_SUB);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
SpaceClip *sc = CTX_wm_space_clip(C);
ED_clip_select_all(sc, SEL_DESELECT, nullptr);
}
do_lasso_select_marker(C, mcoords, mcoords_len, select);
MEM_freeN((void *)mcoords);
return OPERATOR_FINISHED;
if (mcoords.is_empty()) {
return OPERATOR_PASS_THROUGH;
}
return OPERATOR_PASS_THROUGH;
const eSelectOp sel_op = eSelectOp(RNA_enum_get(op->ptr, "mode"));
const bool select = (sel_op != SEL_OP_SUB);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
SpaceClip *sc = CTX_wm_space_clip(C);
ED_clip_select_all(sc, SEL_DESELECT, nullptr);
}
do_lasso_select_marker(C, mcoords, select);
return OPERATOR_FINISHED;
}
void CLIP_OT_select_lasso(wmOperatorType *ot)

View File

@@ -954,7 +954,7 @@ static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
KeyframeEdit_LassoData data_lasso = {nullptr};
KeyframeEdit_LassoData data_lasso{};
rcti rect;
rctf rect_fl;
@@ -966,8 +966,8 @@ static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
}
data_lasso.rectf_view = &rect_fl;
data_lasso.mcoords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcoords_len);
if (data_lasso.mcoords == nullptr) {
data_lasso.mcoords = WM_gesture_lasso_path_to_array(C, op);
if (data_lasso.mcoords.is_empty()) {
return OPERATOR_CANCELLED;
}
@@ -988,7 +988,7 @@ static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
}
/* Get settings from operator. */
BLI_lasso_boundbox(&rect, data_lasso.mcoords, data_lasso.mcoords_len);
BLI_lasso_boundbox(&rect, data_lasso.mcoords);
BLI_rctf_rcti_copy(&rect_fl, &rect);
/* Apply box_select action. */
@@ -1000,8 +1000,6 @@ static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
&ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso);
}
MEM_freeN((void *)data_lasso.mcoords);
/* Send notifier that keyframe selection has changed. */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, nullptr);

View File

@@ -964,10 +964,7 @@ static int node_lasso_select_invoke(bContext *C, wmOperator *op, const wmEvent *
return WM_gesture_lasso_invoke(C, op, event);
}
static bool do_lasso_select_node(bContext *C,
const int mcoords[][2],
const int mcoords_len,
eSelectOp sel_op)
static bool do_lasso_select_node(bContext *C, const Span<int2> mcoords, eSelectOp sel_op)
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree &node_tree = *snode->edittree;
@@ -984,7 +981,7 @@ static bool do_lasso_select_node(bContext *C,
}
/* Get rectangle from operator. */
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
for (bNode *node : node_tree.all_nodes()) {
if (select && (node->flag & NODE_SELECT)) {
@@ -1016,7 +1013,7 @@ static bool do_lasso_select_node(bContext *C,
if (UI_view2d_view_to_region_clip(
&region->v2d, center.x, center.y, &screen_co.x, &screen_co.y) &&
BLI_rcti_isect_pt(&rect, screen_co.x, screen_co.y) &&
BLI_lasso_is_point_inside(mcoords, mcoords_len, screen_co.x, screen_co.y, INT_MAX))
BLI_lasso_is_point_inside(mcoords, screen_co.x, screen_co.y, INT_MAX))
{
nodeSetSelected(node, select);
changed = true;
@@ -1035,19 +1032,17 @@ static bool do_lasso_select_node(bContext *C,
static int node_lasso_select_exec(bContext *C, wmOperator *op)
{
int mcoords_len;
const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
const Array<int2> mcoords = WM_gesture_lasso_path_to_array(C, op);
if (mcoords) {
const eSelectOp sel_op = (eSelectOp)RNA_enum_get(op->ptr, "mode");
do_lasso_select_node(C, mcoords, mcoords_len, sel_op);
MEM_freeN((void *)mcoords);
return OPERATOR_FINISHED;
if (mcoords.is_empty()) {
return OPERATOR_PASS_THROUGH;
}
return OPERATOR_PASS_THROUGH;
const eSelectOp sel_op = (eSelectOp)RNA_enum_get(op->ptr, "mode");
do_lasso_select_node(C, mcoords, sel_op);
return OPERATOR_FINISHED;
}
void NODE_OT_select_lasso(wmOperatorType *ot)

View File

@@ -106,6 +106,9 @@
// #include "BLI_time_utildefines.h"
using blender::Array;
using blender::int2;
using blender::Span;
using blender::Vector;
/* -------------------------------------------------------------------- */
@@ -417,8 +420,7 @@ struct LassoSelectUserData {
const rcti *rect;
const rctf *rect_fl;
rctf _rect_fl;
const int (*mcoords)[2];
int mcoords_len;
Span<int2> mcoords;
eSelectOp sel_op;
eBezTriple_Flag select_flag;
@@ -431,8 +433,7 @@ struct LassoSelectUserData {
static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data,
const ViewContext *vc,
const rcti *rect,
const int (*mcoords)[2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
r_data->vc = vc;
@@ -442,7 +443,6 @@ static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data,
BLI_rctf_rcti_copy(&r_data->_rect_fl, rect);
r_data->mcoords = mcoords;
r_data->mcoords_len = mcoords_len;
r_data->sel_op = sel_op;
/* SELECT by default, but can be changed if needed (only few cases use and respect this). */
r_data->select_flag = (eBezTriple_Flag)SELECT;
@@ -541,14 +541,13 @@ static void do_lasso_select_pose__do_tag(void *user_data,
}
if (BLI_rctf_isect_segment(data->rect_fl, screen_co_a, screen_co_b) &&
BLI_lasso_is_edge_inside(
data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX))
BLI_lasso_is_edge_inside(data->mcoords, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX))
{
pchan->bone->flag |= BONE_DONE;
data->is_changed = true;
}
}
static void do_lasso_tag_pose(const ViewContext *vc, const int mcoords[][2], const int mcoords_len)
static void do_lasso_tag_pose(const ViewContext *vc, const Span<int2> mcoords)
{
LassoSelectUserData data;
rcti rect;
@@ -557,10 +556,9 @@ static void do_lasso_tag_pose(const ViewContext *vc, const int mcoords[][2], con
return;
}
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
view3d_userdata_lassoselect_init(
&data, vc, &rect, mcoords, mcoords_len, static_cast<eSelectOp>(0));
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, static_cast<eSelectOp>(0));
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
@@ -572,8 +570,7 @@ static void do_lasso_tag_pose(const ViewContext *vc, const int mcoords[][2], con
}
static bool do_lasso_select_objects(const ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
View3D *v3d = vc->v3d;
@@ -590,7 +587,6 @@ static bool do_lasso_select_objects(const ViewContext *vc,
const bool is_inside = (ED_view3d_project_base(vc->region, base, region_co) ==
V3D_PROJ_RET_OK) &&
BLI_lasso_is_point_inside(mcoords,
mcoords_len,
int(region_co[0]),
int(region_co[1]),
/* Dummy value. */
@@ -704,8 +700,7 @@ static bool do_pose_tag_select_op_exec(blender::MutableSpan<Base *> bases, const
}
static bool do_lasso_select_pose(const ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
blender::Vector<Base *> bases = do_pose_tag_select_op_prepare(vc);
@@ -716,7 +711,7 @@ static bool do_lasso_select_pose(const ViewContext *vc,
Base *base_iter = bases[i];
Object *ob_iter = base_iter->object;
ED_view3d_viewcontext_init_object(&vc_temp, ob_iter);
do_lasso_tag_pose(&vc_temp, mcoords, mcoords_len);
do_lasso_tag_pose(&vc_temp, mcoords);
}
const bool changed_multi = do_pose_tag_select_op_exec(bases, sel_op);
@@ -735,10 +730,9 @@ static void do_lasso_select_mesh__doSelectVert(void *user_data,
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(user_data);
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
const bool is_inside =
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, screen_co[0], screen_co[1], IS_CLIPPED));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
@@ -768,10 +762,8 @@ static void do_lasso_select_mesh__doSelectEdge_pass0(void *user_data,
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
const bool is_inside =
(is_visible && edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) &&
BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), IS_CLIPPED) &&
BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, UNPACK2(screen_co_b), IS_CLIPPED));
BLI_lasso_is_point_inside(data->mcoords, UNPACK2(screen_co_a), IS_CLIPPED) &&
BLI_lasso_is_point_inside(data->mcoords, UNPACK2(screen_co_b), IS_CLIPPED));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
@@ -796,7 +788,6 @@ static void do_lasso_select_mesh__doSelectEdge_pass1(void *user_data,
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
const bool is_inside = (is_visible && BLI_lasso_is_edge_inside(data->mcoords,
data->mcoords_len,
UNPACK2(screen_co_a),
UNPACK2(screen_co_b),
IS_CLIPPED));
@@ -814,10 +805,9 @@ static void do_lasso_select_mesh__doSelectFace(void *user_data,
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(user_data);
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
const bool is_inside =
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, screen_co[0], screen_co[1], IS_CLIPPED));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
@@ -827,8 +817,7 @@ static void do_lasso_select_mesh__doSelectFace(void *user_data,
static bool do_lasso_select_mesh(const ViewContext *vc,
wmGenericUserData *wm_userdata,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
LassoSelectUserData data;
@@ -837,9 +826,9 @@ static bool do_lasso_select_mesh(const ViewContext *vc,
BLI_assert(vc->em == BKE_editmesh_from_object(vc->obedit));
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, mcoords_len, sel_op);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, sel_op);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
if (vc->em->bm->totvertsel) {
@@ -861,7 +850,7 @@ static bool do_lasso_select_mesh(const ViewContext *vc,
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, ts->selectmode);
esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(
vc->depsgraph, vc->region, vc->v3d, mcoords, mcoords_len, &rect, nullptr);
vc->depsgraph, vc->region, vc->v3d, mcoords, &rect, nullptr);
}
}
@@ -927,7 +916,7 @@ static void do_lasso_select_curve__doSelect(void *user_data,
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(user_data);
const bool is_inside = BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED);
data->mcoords, screen_co[0], screen_co[1], IS_CLIPPED);
if (bp) {
const bool is_select = bp->f1 & SELECT;
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
@@ -960,17 +949,16 @@ static void do_lasso_select_curve__doSelect(void *user_data,
}
static bool do_lasso_select_curve(const ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
const bool deselect_all = (sel_op == SEL_OP_SET);
LassoSelectUserData data;
rcti rect;
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, mcoords_len, sel_op);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, sel_op);
Curve *curve = (Curve *)vc->obedit->data;
ListBase *nurbs = BKE_curve_editNurbs_get(curve);
@@ -1001,10 +989,9 @@ static void do_lasso_select_lattice__doSelect(void *user_data,
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(user_data);
const bool is_select = bp->f1 & SELECT;
const bool is_inside =
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, screen_co[0], screen_co[1], IS_CLIPPED));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
@@ -1012,16 +999,15 @@ static void do_lasso_select_lattice__doSelect(void *user_data,
}
}
static bool do_lasso_select_lattice(const ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
LassoSelectUserData data;
rcti rect;
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, mcoords_len, sel_op);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, sel_op);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
data.is_changed |= ED_lattice_flags_set(vc->obedit, 0);
@@ -1049,7 +1035,7 @@ static void do_lasso_select_armature__doSelectBone(void *user_data,
if (screen_co_a[0] != IS_CLIPPED) {
if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_a)) &&
BLI_lasso_is_point_inside(data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), INT_MAX))
BLI_lasso_is_point_inside(data->mcoords, UNPACK2(screen_co_a), INT_MAX))
{
is_inside_flag |= BONESEL_ROOT;
}
@@ -1060,7 +1046,7 @@ static void do_lasso_select_armature__doSelectBone(void *user_data,
if (screen_co_b[0] != IS_CLIPPED) {
if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_b)) &&
BLI_lasso_is_point_inside(data->mcoords, data->mcoords_len, UNPACK2(screen_co_b), INT_MAX))
BLI_lasso_is_point_inside(data->mcoords, UNPACK2(screen_co_b), INT_MAX))
{
is_inside_flag |= BONESEL_TIP;
}
@@ -1072,7 +1058,7 @@ static void do_lasso_select_armature__doSelectBone(void *user_data,
if (is_ignore_flag == 0) {
if (is_inside_flag == (BONE_ROOTSEL | BONE_TIPSEL) ||
BLI_lasso_is_edge_inside(
data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX))
data->mcoords, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX))
{
is_inside_flag |= BONESEL_BONE;
}
@@ -1101,8 +1087,7 @@ static void do_lasso_select_armature__doSelectBone_clip_content(void *user_data,
return;
}
if (BLI_lasso_is_edge_inside(
data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX))
if (BLI_lasso_is_edge_inside(data->mcoords, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX))
{
is_inside_flag |= BONESEL_BONE;
}
@@ -1111,16 +1096,15 @@ static void do_lasso_select_armature__doSelectBone_clip_content(void *user_data,
}
static bool do_lasso_select_armature(const ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
LassoSelectUserData data;
rcti rect;
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, mcoords_len, sel_op);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, sel_op);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
data.is_changed |= ED_armature_edit_deselect_all_visible(vc->obedit);
@@ -1158,10 +1142,9 @@ static void do_lasso_select_mball__doSelectElem(void *user_data,
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(user_data);
const bool is_select = ml->flag & SELECT;
const bool is_inside =
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], INT_MAX));
const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, screen_co[0], screen_co[1], INT_MAX));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
SET_FLAG_FROM_TEST(ml->flag, sel_op_result, SELECT);
@@ -1169,8 +1152,7 @@ static void do_lasso_select_mball__doSelectElem(void *user_data,
}
}
static bool do_lasso_select_meta(const ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
LassoSelectUserData data;
@@ -1178,9 +1160,9 @@ static bool do_lasso_select_meta(const ViewContext *vc,
MetaBall *mb = (MetaBall *)vc->obedit->data;
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, mcoords_len, sel_op);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, sel_op);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
data.is_changed |= BKE_mball_deselect_all(mb);
@@ -1195,8 +1177,7 @@ static bool do_lasso_select_meta(const ViewContext *vc,
}
static bool do_lasso_select_grease_pencil(const ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
using namespace blender;
@@ -1225,15 +1206,14 @@ static bool do_lasso_select_grease_pencil(const ViewContext *vc,
}
const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
const float4x4 projection = ED_view3d_ob_project_mat_get_from_obmat(vc->rv3d, layer_to_world);
changed = ed::curves::select_lasso(
*vc,
info.drawing.strokes_for_write(),
deformation.positions,
projection,
elements,
selection_domain,
Span<int2>(reinterpret_cast<const int2 *>(mcoords), mcoords_len),
sel_op);
changed = ed::curves::select_lasso(*vc,
info.drawing.strokes_for_write(),
deformation.positions,
projection,
elements,
selection_domain,
mcoords,
sel_op);
}
if (changed) {
@@ -1259,10 +1239,9 @@ static void do_lasso_select_meshobject__doSelectVert(void *user_data,
user_data);
LassoSelectUserData *data = &mesh_data->lasso_data;
const bool is_select = mesh_data->select_vert[index];
const bool is_inside =
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
BLI_lasso_is_point_inside(
data->mcoords, screen_co[0], screen_co[1], IS_CLIPPED));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
mesh_data->select_vert[index] = sel_op_result == 1;
@@ -1271,8 +1250,7 @@ static void do_lasso_select_meshobject__doSelectVert(void *user_data,
}
static bool do_lasso_select_paintvert(const ViewContext *vc,
wmGenericUserData *wm_userdata,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
using namespace blender;
@@ -1291,7 +1269,7 @@ static bool do_lasso_select_paintvert(const ViewContext *vc,
changed |= paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
}
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
EditSelectBuf_Cache *esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
if (use_zbuf) {
@@ -1299,7 +1277,7 @@ static bool do_lasso_select_paintvert(const ViewContext *vc,
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_VERTEX);
esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(
vc->depsgraph, vc->region, vc->v3d, mcoords, mcoords_len, &rect, nullptr);
vc->depsgraph, vc->region, vc->v3d, mcoords, &rect, nullptr);
}
}
@@ -1316,7 +1294,7 @@ static bool do_lasso_select_paintvert(const ViewContext *vc,
LassoSelectUserData_ForMeshVert data;
data.select_vert = select_vert.span;
view3d_userdata_lassoselect_init(&data.lasso_data, vc, &rect, mcoords, mcoords_len, sel_op);
view3d_userdata_lassoselect_init(&data.lasso_data, vc, &rect, mcoords, sel_op);
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
@@ -1339,8 +1317,7 @@ static bool do_lasso_select_paintvert(const ViewContext *vc,
}
static bool do_lasso_select_paintface(const ViewContext *vc,
wmGenericUserData *wm_userdata,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
Object *ob = vc->obact;
@@ -1357,14 +1334,14 @@ static bool do_lasso_select_paintface(const ViewContext *vc,
changed |= paintface_deselect_all_visible(vc->C, ob, SEL_DESELECT, false);
}
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
EditSelectBuf_Cache *esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
if (esel == nullptr) {
editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_FACE);
esel = static_cast<EditSelectBuf_Cache *>(wm_userdata->data);
esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(
vc->depsgraph, vc->region, vc->v3d, mcoords, mcoords_len, &rect, nullptr);
vc->depsgraph, vc->region, vc->v3d, mcoords, &rect, nullptr);
}
if (esel->select_bitmap) {
@@ -1379,8 +1356,7 @@ static bool do_lasso_select_paintface(const ViewContext *vc,
static bool view3d_lasso_select(bContext *C,
ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const eSelectOp sel_op)
{
using namespace blender;
@@ -1392,19 +1368,22 @@ static bool view3d_lasso_select(bContext *C,
if (vc->obedit == nullptr) { /* Object Mode */
if (BKE_paint_select_face_test(ob)) {
changed_multi |= do_lasso_select_paintface(vc, wm_userdata, mcoords, mcoords_len, sel_op);
changed_multi |= do_lasso_select_paintface(vc, wm_userdata, mcoords, sel_op);
}
else if (BKE_paint_select_vert_test(ob)) {
changed_multi |= do_lasso_select_paintvert(vc, wm_userdata, mcoords, mcoords_len, sel_op);
changed_multi |= do_lasso_select_paintvert(vc, wm_userdata, mcoords, sel_op);
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
changed_multi |= PE_lasso_select(C, mcoords, mcoords_len, sel_op) != OPERATOR_CANCELLED;
changed_multi |= PE_lasso_select(C,
reinterpret_cast<const int(*)[2]>(mcoords.data()),
mcoords.size(),
sel_op) != OPERATOR_CANCELLED;
}
else if (ob &&
((ob->mode & OB_MODE_POSE) | ((ob->mode & OB_MODE_WEIGHT_PAINT) &&
BKE_object_pose_armature_get_with_wpaint_check(ob))))
{
changed_multi |= do_lasso_select_pose(vc, mcoords, mcoords_len, sel_op);
changed_multi |= do_lasso_select_pose(vc, mcoords, sel_op);
if (changed_multi) {
ED_outliner_select_sync_from_pose_bone_tag(C);
}
@@ -1415,7 +1394,7 @@ static bool view3d_lasso_select(bContext *C,
/* pass */
}
else {
changed_multi |= do_lasso_select_objects(vc, mcoords, mcoords_len, sel_op);
changed_multi |= do_lasso_select_objects(vc, mcoords, sel_op);
if (changed_multi) {
ED_outliner_select_sync_from_object_tag(C);
}
@@ -1433,23 +1412,23 @@ static bool view3d_lasso_select(bContext *C,
switch (vc->obedit->type) {
case OB_MESH:
changed = do_lasso_select_mesh(vc, wm_userdata, mcoords, mcoords_len, sel_op);
changed = do_lasso_select_mesh(vc, wm_userdata, mcoords, sel_op);
break;
case OB_CURVES_LEGACY:
case OB_SURF:
changed = do_lasso_select_curve(vc, mcoords, mcoords_len, sel_op);
changed = do_lasso_select_curve(vc, mcoords, sel_op);
break;
case OB_LATTICE:
changed = do_lasso_select_lattice(vc, mcoords, mcoords_len, sel_op);
changed = do_lasso_select_lattice(vc, mcoords, sel_op);
break;
case OB_ARMATURE:
changed = do_lasso_select_armature(vc, mcoords, mcoords_len, sel_op);
changed = do_lasso_select_armature(vc, mcoords, sel_op);
if (changed) {
ED_outliner_select_sync_from_edit_bone_tag(C);
}
break;
case OB_MBALL:
changed = do_lasso_select_meta(vc, mcoords, mcoords_len, sel_op);
changed = do_lasso_select_meta(vc, mcoords, sel_op);
break;
case OB_CURVES: {
Curves &curves_id = *static_cast<Curves *>(vc->obedit->data);
@@ -1459,15 +1438,14 @@ static bool view3d_lasso_select(bContext *C,
const bke::AttrDomain selection_domain = bke::AttrDomain(curves_id.selection_domain);
const IndexRange elements(curves.attributes().domain_size(selection_domain));
const float4x4 projection = ED_view3d_ob_project_mat_get(vc->rv3d, vc->obedit);
changed = ed::curves::select_lasso(
*vc,
curves,
deformation.positions,
projection,
elements,
selection_domain,
Span<int2>(reinterpret_cast<const int2 *>(mcoords), mcoords_len),
sel_op);
changed = ed::curves::select_lasso(*vc,
curves,
deformation.positions,
projection,
elements,
selection_domain,
mcoords,
sel_op);
if (changed) {
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
@@ -1477,7 +1455,7 @@ static bool view3d_lasso_select(bContext *C,
break;
}
case OB_GREASE_PENCIL: {
changed = do_lasso_select_grease_pencil(vc, mcoords, mcoords_len, sel_op);
changed = do_lasso_select_grease_pencil(vc, mcoords, sel_op);
break;
}
default:
@@ -1503,28 +1481,25 @@ static bool view3d_lasso_select(bContext *C,
* with short array we convert */
static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
{
int mcoords_len;
const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
if (mcoords) {
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
view3d_operator_needs_opengl(C);
BKE_object_update_select_id(CTX_data_main(C));
/* setup view context for argument to callbacks */
ViewContext vc = ED_view3d_viewcontext_init(C, depsgraph);
eSelectOp sel_op = static_cast<eSelectOp>(RNA_enum_get(op->ptr, "mode"));
bool changed_multi = view3d_lasso_select(C, &vc, mcoords, mcoords_len, sel_op);
MEM_freeN((void *)mcoords);
if (changed_multi) {
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
Array<int2> mcoords = WM_gesture_lasso_path_to_array(C, op);
if (mcoords.is_empty()) {
return OPERATOR_PASS_THROUGH;
}
return OPERATOR_PASS_THROUGH;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
view3d_operator_needs_opengl(C);
BKE_object_update_select_id(CTX_data_main(C));
/* setup view context for argument to callbacks */
ViewContext vc = ED_view3d_viewcontext_init(C, depsgraph);
eSelectOp sel_op = static_cast<eSelectOp>(RNA_enum_get(op->ptr, "mode"));
bool changed_multi = view3d_lasso_select(C, &vc, mcoords, sel_op);
if (changed_multi) {
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
void VIEW3D_OT_select_lasso(wmOperatorType *ot)

View File

@@ -65,6 +65,8 @@
#include "uvedit_intern.hh"
using blender::Array;
using blender::int2;
using blender::Span;
using blender::Vector;
@@ -3892,15 +3894,14 @@ void UV_OT_select_circle(wmOperatorType *ot)
static bool do_lasso_select_mesh_uv_is_point_inside(const ARegion *region,
const rcti *clip_rect,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const float co_test[2])
{
int co_screen[2];
if (UI_view2d_view_to_region_clip(
&region->v2d, co_test[0], co_test[1], &co_screen[0], &co_screen[1]) &&
BLI_rcti_isect_pt_v(clip_rect, co_screen) &&
BLI_lasso_is_point_inside(mcoords, mcoords_len, co_screen[0], co_screen[1], V2D_IS_CLIPPED))
BLI_lasso_is_point_inside(mcoords, co_screen[0], co_screen[1], V2D_IS_CLIPPED))
{
return true;
}
@@ -3909,8 +3910,7 @@ static bool do_lasso_select_mesh_uv_is_point_inside(const ARegion *region,
static bool do_lasso_select_mesh_uv_is_edge_inside(const ARegion *region,
const rcti *clip_rect,
const int mcoords[][2],
const int mcoords_len,
const Span<int2> mcoords,
const float co_test_a[2],
const float co_test_b[2])
{
@@ -3919,17 +3919,14 @@ static bool do_lasso_select_mesh_uv_is_edge_inside(const ARegion *region,
&region->v2d, co_test_a, co_test_b, co_screen_a, co_screen_b) &&
BLI_rcti_isect_segment(clip_rect, co_screen_a, co_screen_b) &&
BLI_lasso_is_edge_inside(
mcoords, mcoords_len, UNPACK2(co_screen_a), UNPACK2(co_screen_b), V2D_IS_CLIPPED))
mcoords, UNPACK2(co_screen_a), UNPACK2(co_screen_b), V2D_IS_CLIPPED))
{
return true;
}
return false;
}
static bool do_lasso_select_mesh_uv(bContext *C,
const int mcoords[][2],
const int mcoords_len,
const eSelectOp sel_op)
static bool do_lasso_select_mesh_uv(bContext *C, const Span<int2> mcoords, const eSelectOp sel_op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
const ARegion *region = CTX_wm_region(C);
@@ -3955,7 +3952,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
bool changed_multi = false;
rcti rect;
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
Vector<Object *> objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
scene, view_layer, nullptr);
@@ -3982,7 +3979,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
if (select != uvedit_face_select_test(scene, efa, offsets)) {
float cent[2];
BM_face_uv_calc_center_median(efa, offsets.uv, cent);
if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, mcoords_len, cent)) {
if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, cent)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
changed = true;
}
@@ -4006,9 +4003,8 @@ static bool do_lasso_select_mesh_uv(bContext *C,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, mcoords_len, luv) &&
do_lasso_select_mesh_uv_is_point_inside(
region, &rect, mcoords, mcoords_len, luv_prev))
if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, luv) &&
do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, luv_prev))
{
uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets);
do_second_pass = false;
@@ -4031,9 +4027,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
if (do_lasso_select_mesh_uv_is_edge_inside(
region, &rect, mcoords, mcoords_len, luv, luv_prev))
{
if (do_lasso_select_mesh_uv_is_edge_inside(region, &rect, mcoords, luv, luv_prev)) {
uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets);
changed = true;
}
@@ -4054,8 +4048,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (select != uvedit_uv_select_test(scene, l, offsets)) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, mcoords_len, luv))
{
if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, luv)) {
uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
changed = true;
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
@@ -4093,18 +4086,15 @@ static bool do_lasso_select_mesh_uv(bContext *C,
static int uv_lasso_select_exec(bContext *C, wmOperator *op)
{
int mcoords_len;
const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
if (mcoords) {
const eSelectOp sel_op = eSelectOp(RNA_enum_get(op->ptr, "mode"));
bool changed = do_lasso_select_mesh_uv(C, mcoords, mcoords_len, sel_op);
MEM_freeN((void *)mcoords);
return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
Array<int2> mcoords = WM_gesture_lasso_path_to_array(C, op);
if (mcoords.is_empty()) {
return OPERATOR_PASS_THROUGH;
}
return OPERATOR_PASS_THROUGH;
const eSelectOp sel_op = eSelectOp(RNA_enum_get(op->ptr, "mode"));
bool changed = do_lasso_select_mesh_uv(C, mcoords, sel_op);
return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void UV_OT_select_lasso(wmOperatorType *ot)

View File

@@ -19,8 +19,10 @@
#include "DNA_windowmanager_types.h"
#include "BLI_array.hh"
#include "BLI_compiler_attrs.h"
#include "BLI_function_ref.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_sys_types.h"
#include "WM_keymap.hh"
@@ -1279,10 +1281,8 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event);
void WM_gesture_lasso_cancel(bContext *C, wmOperator *op);
/**
* helper function, we may want to add options for conversion to view space
*
* caller must free.
*/
const int (*WM_gesture_lasso_path_to_array(bContext *C, wmOperator *op, int *mcoords_len))[2];
blender::Array<blender::int2> WM_gesture_lasso_path_to_array(bContext *C, wmOperator *op);
int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event);
/**

View File

@@ -31,6 +31,9 @@
#include "BIF_glutil.hh"
using blender::Array;
using blender::int2;
wmGesture *WM_gesture_new(wmWindow *window, const ARegion *region, const wmEvent *event, int type)
{
wmGesture *gesture = static_cast<wmGesture *>(MEM_callocN(sizeof(wmGesture), "new gesture"));
@@ -288,8 +291,7 @@ static void draw_filled_lasso(wmGesture *gt)
{
const short *lasso = (short *)gt->customdata;
const int mcoords_len = gt->points;
int(*mcoords)[2] = static_cast<int(*)[2]>(
MEM_mallocN(sizeof(*mcoords) * (mcoords_len + 1), __func__));
Array<int2> mcoords(mcoords_len);
int i;
rcti rect;
const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
@@ -299,7 +301,7 @@ static void draw_filled_lasso(wmGesture *gt)
mcoords[i][1] = lasso[1];
}
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
BLI_lasso_boundbox(&rect, mcoords);
BLI_rcti_translate(&rect, gt->winrct.xmin, gt->winrct.ymin);
BLI_rcti_isect(&gt->winrct, &rect, &rect);
@@ -317,7 +319,6 @@ static void draw_filled_lasso(wmGesture *gt)
rect.xmax,
rect.ymax,
mcoords,
mcoords_len,
draw_filled_lasso_px_cb,
&lasso_fill_data);
@@ -337,8 +338,6 @@ static void draw_filled_lasso(wmGesture *gt)
GPU_blend(GPU_BLEND_NONE);
}
MEM_freeN(mcoords);
}
static void wm_gesture_draw_lasso(wmGesture *gt, bool filled)

View File

@@ -18,6 +18,7 @@
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#include "BLI_math_vector_types.hh"
#include "BLI_rect.h"
#include "BKE_context.hh"
@@ -33,6 +34,9 @@
#include "RNA_access.hh"
using blender::Array;
using blender::int2;
/* -------------------------------------------------------------------- */
/** \name Internal Gesture Utilities
*
@@ -620,38 +624,29 @@ void WM_gesture_lines_cancel(bContext *C, wmOperator *op)
gesture_modal_end(C, op);
}
const int (*WM_gesture_lasso_path_to_array(bContext * /*C*/,
wmOperator *op,
int *r_mcoords_len))[2]
Array<int2> WM_gesture_lasso_path_to_array(bContext * /*C*/, wmOperator *op)
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "path");
int(*mcoords)[2] = nullptr;
BLI_assert(prop != nullptr);
if (prop) {
const int len = RNA_property_collection_length(op->ptr, prop);
if (len) {
int i = 0;
mcoords = static_cast<int(*)[2]>(MEM_mallocN(sizeof(int[2]) * len, __func__));
RNA_PROP_BEGIN (op->ptr, itemptr, prop) {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
mcoords[i][0] = int(loc[0]);
mcoords[i][1] = int(loc[1]);
i++;
}
RNA_PROP_END;
}
*r_mcoords_len = len;
if (!prop) {
return {};
}
else {
*r_mcoords_len = 0;
const int len = RNA_property_collection_length(op->ptr, prop);
if (len == 0) {
return {};
}
/* cast for 'const' */
int i = 0;
Array<int2> mcoords(len);
RNA_PROP_BEGIN (op->ptr, itemptr, prop) {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
mcoords[i] = int2(loc[0], loc[1]);
i++;
}
RNA_PROP_END;
return mcoords;
}