45 "use_front_faces_only",
48 "Affect only faces facing towards the view");
52 "use_limit_to_segment",
55 "Apply the gesture action only to the area that is contained within the "
56 "segment without extending its effect to the entire line");
78 float view_dir[3] = {0.0f, 0.0f, 1.0f};
91static void lasso_px_cb(
int x,
int x_end,
int y,
void *user_data)
95 int index = (y * lasso->
width) + x;
96 int index_end = (y * lasso->
width) + x_end;
99 }
while (++index != index_end);
110 if (mcoords.
size() <= 1) {
114 std::unique_ptr<GestureData> gesture_data = std::make_unique<GestureData>();
120 gesture_data->vc.obact);
122 const int lasso_width = 1 + gesture_data->lasso.boundbox.xmax -
123 gesture_data->lasso.boundbox.xmin;
124 const int lasso_height = 1 + gesture_data->lasso.boundbox.ymax -
125 gesture_data->lasso.boundbox.ymin;
126 gesture_data->lasso.width = lasso_width;
127 gesture_data->lasso.mask_px.resize(lasso_width * lasso_height);
130 gesture_data->lasso.boundbox.ymin,
131 gesture_data->lasso.boundbox.xmax,
132 gesture_data->lasso.boundbox.ymax,
139 gesture_data->true_clip_planes,
140 gesture_data->vc.region,
141 gesture_data->vc.obact,
142 &gesture_data->lasso.boundbox);
144 gesture_data->gesture_points.reinitialize(mcoords.
size());
146 gesture_data->gesture_points[i][0] = mcoords[i][0];
147 gesture_data->gesture_points[i][1] = mcoords[i][1];
155 std::unique_ptr<GestureData> gesture_data = std::make_unique<GestureData>();
165 &bb, gesture_data->true_clip_planes, gesture_data->vc.region, gesture_data->vc.obact, &rect);
167 gesture_data->gesture_points.reinitialize(4);
169 gesture_data->gesture_points[0][0] = rect.
xmax;
170 gesture_data->gesture_points[0][1] = rect.
ymax;
172 gesture_data->gesture_points[1][0] = rect.
xmax;
173 gesture_data->gesture_points[1][1] = rect.
ymin;
175 gesture_data->gesture_points[2][0] = rect.
xmin;
176 gesture_data->gesture_points[2][1] = rect.
ymin;
178 gesture_data->gesture_points[3][0] = rect.
xmin;
179 gesture_data->gesture_points[3][1] = rect.
ymax;
196 float plane_point_object_space[3];
197 mul_v3_m4v3(plane_point_object_space, gesture_data.
vc.
obact->world_to_object().ptr(), p1);
204 float line_points[2][2],
205 float r_plane_points[4][3],
206 float r_offset_plane_points[2][3])
208 float depth_point[3];
211 gesture_data.
vc.
v3d, gesture_data.
vc.
region, depth_point, line_points[0], r_plane_points[0]);
213 gesture_data.
vc.
v3d, gesture_data.
vc.
region, depth_point, line_points[1], r_plane_points[3]);
217 gesture_data.
vc.
v3d, gesture_data.
vc.
region, depth_point, line_points[0], r_plane_points[1]);
219 gesture_data.
vc.
v3d, gesture_data.
vc.
region, depth_point, line_points[1], r_plane_points[2]);
222 normal_tri_v3(normal, r_plane_points[0], r_plane_points[1], r_plane_points[2]);
223 add_v3_v3v3(r_offset_plane_points[0], r_plane_points[0], normal);
224 add_v3_v3v3(r_offset_plane_points[1], r_plane_points[3], normal);
229 std::unique_ptr<GestureData> gesture_data = std::make_unique<GestureData>();
231 gesture_data->line.use_side_planes =
RNA_boolean_get(op->
ptr,
"use_limit_to_segment");
235 float line_points[2][2];
241 gesture_data->gesture_points.reinitialize(2);
242 gesture_data->gesture_points[0][0] = line_points[0][0];
243 gesture_data->gesture_points[0][1] = line_points[0][1];
244 gesture_data->gesture_points[1][0] = line_points[1][0];
245 gesture_data->gesture_points[1][1] = line_points[1][1];
249 float plane_points[4][3];
250 float offset_plane_points[2][3];
254 const bool flip = gesture_data->line.flip ^ (!gesture_data->vc.rv3d->is_persp);
268 offset_plane_points[0]);
274 offset_plane_points[1]);
284static void flip_plane(
float out[4],
const float in[4],
const char symm)
311 for (
int j = 0; j < 4; j++) {
327 float clip_planes[3][4];
333 frustum.
planes = clip_planes;
338 return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum);
345 float clip_planes[4][4];
350 frustum.
planes = clip_planes;
351 frustum.num_planes = 4;
355 switch (gesture_data.selection_type) {
356 case SelectionType::Inside:
357 return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum);
358 case SelectionType::Outside:
362 if (gesture_data.shape_type == ShapeType::Lasso) {
365 return BKE_pbvh_node_frustum_exclude_AABB(&node, &frustum);
376 case ShapeType::Lasso:
379 case ShapeType::Line:
394 scr_co_s[0] = scr_co_f[0];
395 scr_co_s[1] = scr_co_f[1];
406 const bool bitmap_result = lasso.
mask_px[scr_co_s[1] * lasso.
width + scr_co_s[0]].test();
408 case SelectionType::Inside:
409 return bitmap_result;
410 case SelectionType::Outside:
411 return !bitmap_result;
422 if (!is_effected_front_face) {
427 case ShapeType::Box: {
429 return ((is_contained && gesture_data.
selection_type == SelectionType::Inside) ||
430 (!is_contained && gesture_data.
selection_type == SelectionType::Outside));
432 case ShapeType::Lasso:
434 case ShapeType::Line:
450 for (
const int i : positions.index_range()) {
451 if (!
is_affected(gesture_data, positions[i], normals[i])) {
461 operation->
begin(C, op, gesture_data);
463 for (
int symmpass = 0; symmpass <= gesture_data.
symm; symmpass++) {
472 operation->
end(C, gesture_data);
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
#define BLI_assert_unreachable()
void BLI_bitmap_draw_2d_poly_v2i_n(int xmin, int ymin, int xmax, int ymax, blender::Span< blender::int2 > verts, void(*callback)(int x, int x_end, int y, void *), void *user_data)
void BLI_lasso_boundbox(rcti *rect, blender::Span< blender::int2 > mcoords)
bool isect_point_planes_v3(const float(*planes)[4], int totplane, const float p[3])
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
void mul_m3_v3(const float M[3][3], float r[3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void negate_m4(float R[4][4])
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
bool BLI_rcti_isect_pt(const struct rcti *rect, int x, int y)
blender::float2 ED_view3d_project_float_v2_m4(const ARegion *region, const float co[3], const blender::float4x4 &mat)
void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *region, const Object *ob, const rcti *rect)
void ED_view3d_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
blender::float4x4 ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob)
Read Guarded memory(de)allocation.
IndexRange index_range() const
const Depsgraph * depsgraph
pbvh::Tree * pbvh_get(Object &object)
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
static void update_affected_nodes_by_line_plane(GestureData &gesture_data)
std::unique_ptr< GestureData > init_from_box(bContext *C, wmOperator *op)
void operator_properties(wmOperatorType *ot, ShapeType shapeType)
static void flip_plane(float out[4], const float in[4], const char symm)
std::unique_ptr< GestureData > init_from_polyline(bContext *C, wmOperator *op)
static void update_affected_nodes(GestureData &gesture_data)
static void line_calculate_plane_points(GestureData &gesture_data, float line_points[2][2], float r_plane_points[4][3], float r_offset_plane_points[2][3])
std::unique_ptr< GestureData > init_from_line(bContext *C, wmOperator *op)
static void flip_for_symmetry_pass(GestureData &gesture_data, const ePaintSymmetryFlags symmpass)
static void init_common(bContext *C, wmOperator *op, GestureData &gesture_data)
void filter_factors(const GestureData &gesture_data, const Span< float3 > positions, const Span< float3 > normals, const MutableSpan< float > factors)
static bool is_affected_lasso(const GestureData &gesture_data, const float3 &position)
std::unique_ptr< GestureData > init_from_lasso(bContext *C, wmOperator *op)
static void update_affected_nodes_by_clip_planes(GestureData &gesture_data)
bool is_affected(const GestureData &gesture_data, const float3 &position, const float3 &normal)
static void lasso_px_cb(int x, int x_end, int y, void *user_data)
static void line_plane_from_tri(float *r_plane, GestureData &gesture_data, const bool flip, const float p1[3], const float p2[3], const float p3[3])
float3 symmetry_flip(const float3 &src, const ePaintSymmetryFlags symm)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(const Object &object)
bool SCULPT_is_symmetry_iteration_valid(char i, char symm)
void SCULPT_tag_update_overlays(bContext *C)
struct SculptSession * sculpt
ePaintSymmetryFlags symmpass
float3 world_space_view_origin
SelectionType selection_type
IndexMaskMemory node_mask_memory
float3 world_space_view_normal
float true_clip_planes[4][4]
blender::BitVector mask_px
float true_side_plane[2][4]
void(* end)(bContext &, GestureData &)
void(* begin)(bContext &, wmOperator &, GestureData &)
void(* apply_for_symmetry_pass)(bContext &, GestureData &)
Array< int2 > WM_gesture_lasso_path_to_array(bContext *, wmOperator *op)
void WM_operator_properties_border_to_rcti(wmOperator *op, rcti *r_rect)