3D View: move deselect all logic into an option

This removes `VIEW3D_OT_select_or_deselect_all`, adding a
deselect_all option to the `VIEW3D_OT_select` operator.

- Add utility functions to simplify de-selecting all.

- Return true from selection functions when they change the selection
  to avoid redundant updates.

- Use arrays of bases when passing objects between selection utility
  functions since some users require bases.

- Fix logical error in box selection that updated all objects after
  the first hit.
This commit is contained in:
Campbell Barton 2019-03-26 18:47:55 +11:00
parent 30fbf905ef
commit 40f8ddf829
Notes: blender-bot 2023-02-14 03:13:20 +01:00
Referenced by commit 37e3b89506, Fix T63017: selection via lasso does not work properly in X-ray.
Referenced by issue #63001, Can't pick anything with mouse click (Mac only?)
24 changed files with 810 additions and 545 deletions

View File

@ -1047,7 +1047,7 @@ def km_view3d(params):
{"type": params.select_mouse, "value": params.select_mouse_value, **{m: True for m in mods}},
{"properties": [(c, True) for c in props]},
) for operator, props, mods in (
("view3d.select_or_deselect_all" if not params.legacy else "view3d.select", (), ()),
("view3d.select", ("deselect_all",) if not params.legacy else (), ()),
("view3d.select", ("toggle",), ("shift",)),
("view3d.select", ("center", "object"), ("ctrl",)),
("view3d.select", ("enumerate",), ("alt",)),

View File

@ -139,109 +139,8 @@ class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator):
return self.execute(context)
class VIEW3D_OT_select_or_deselect_all(Operator):
"""Select element under the mouse, deselect everything is there's nothing under the mouse"""
bl_label = "Select or Deselect All"
bl_idname = "view3d.select_or_deselect_all"
extend: BoolProperty(
name="Extend",
description="Extend selection instead of deselecting everything first",
default=False,
options={'SKIP_SAVE'},
)
toggle: BoolProperty(
name="Toggle",
description="Toggle the selection",
default=False,
options={'SKIP_SAVE'},
)
deselect: BoolProperty(
name="Deselect",
description="Remove from selection",
default=False,
options={'SKIP_SAVE'},
)
center: BoolProperty(
name="Center",
description="Use the object center when selecting, in editmode used to extend object selection",
default=False,
options={'SKIP_SAVE'},
)
enumerate: BoolProperty(
name="Enumerate",
description="List objects under the mouse (object mode only)",
default=False,
options={'SKIP_SAVE'},
)
object: BoolProperty(
name="Object",
description="Use object selection (editmode only)",
default=False,
options={'SKIP_SAVE'},
)
def invoke(self, context, event):
retval = bpy.ops.view3d.select(
'INVOKE_DEFAULT',
True, # undo push
extend=self.extend,
deselect=self.deselect,
toggle=self.toggle,
center=self.center,
enumerate=self.enumerate,
object=self.object,
)
# Finished means something was selected.
if 'FINISHED' in retval:
return retval
if self.extend or self.toggle or self.deselect:
return retval
active_object = context.active_object
if active_object:
if active_object.mode == 'OBJECT':
select_all = bpy.ops.object.select_all
elif active_object.mode == 'EDIT':
if active_object.type == 'MESH':
select_all = bpy.ops.mesh.select_all
elif active_object.type == 'CURVE':
select_all = bpy.ops.curve.select_all
elif active_object.type == 'SURFACE':
select_all = bpy.ops.curve.select_all
elif active_object.type == 'LATTICE':
select_all = bpy.ops.lattice.select_all
elif active_object.type == 'META':
select_all = bpy.ops.mball.select_all
elif active_object.type == 'ARMATURE':
select_all = bpy.ops.armature.select_all
else:
return retval
elif active_object.mode == 'POSE':
select_all = bpy.ops.pose.select_all
elif active_object.mode == 'PARTICLE_EDIT':
select_all = bpy.ops.particle.select_all
else:
# Don nothing in paint and sculpt modes.
return retval
else:
select_all = bpy.ops.object.select_all
if select_all.poll():
return select_all('INVOKE_DEFAULT', True, action='DESELECT')
else:
return retval
classes = (
VIEW3D_OT_edit_mesh_extrude_individual_move,
VIEW3D_OT_edit_mesh_extrude_move,
VIEW3D_OT_edit_mesh_extrude_shrink_fatten,
VIEW3D_OT_select_or_deselect_all,
)

View File

@ -22,6 +22,7 @@
/** \file
* \ingroup bke
*/
struct Base;
struct BoundBox;
struct Depsgraph;
struct Main;
@ -39,7 +40,7 @@ struct MetaBall *BKE_mball_copy(struct Main *bmain, const struct MetaBall *mb);
void BKE_mball_make_local(struct Main *bmain, struct MetaBall *mb, const bool lib_local);
bool BKE_mball_is_any_selected(const struct MetaBall *mb);
bool BKE_mball_is_any_selected_multi(struct Object **objects, int objects_len);
bool BKE_mball_is_any_selected_multi(struct Base **bases, int bases_len);
bool BKE_mball_is_any_unselected(const struct MetaBall *mb);
bool BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2);
bool BKE_mball_is_basis(struct Object *ob);
@ -63,13 +64,13 @@ void BKE_mball_translate(struct MetaBall *mb, const float offset[3]);
struct MetaElem *BKE_mball_element_add(struct MetaBall *mb, const int type);
int BKE_mball_select_count(const struct MetaBall *mb);
int BKE_mball_select_count_multi(struct Object **objects, int objects_len);
void BKE_mball_select_all(struct MetaBall *mb);
void BKE_mball_select_all_multi(struct Object **objects, int objects_len);
void BKE_mball_deselect_all(struct MetaBall *mb);
void BKE_mball_deselect_all_multi(struct Object **objects, int objects_len);
void BKE_mball_select_swap(struct MetaBall *mb);
void BKE_mball_select_swap_multi(struct Object **objects, int objects_len);
int BKE_mball_select_count_multi(struct Base **bases, int bases_len);
bool BKE_mball_select_all(struct MetaBall *mb);
bool BKE_mball_select_all_multi_ex(struct Base **bases, int bases_len);
bool BKE_mball_deselect_all(struct MetaBall *mb);
bool BKE_mball_deselect_all_multi_ex(struct Base **bases, int bases_len);
bool BKE_mball_select_swap(struct MetaBall *mb);
bool BKE_mball_select_swap_multi_ex(struct Base **bases, int bases_len);
/* **** Depsgraph evaluation **** */

View File

@ -331,10 +331,10 @@ bool BKE_mball_is_any_selected(const MetaBall *mb)
}
bool BKE_mball_is_any_selected_multi(Object **objects, int objects_len)
bool BKE_mball_is_any_selected_multi(Base **bases, int bases_len)
{
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *obedit = bases[base_index]->object;
MetaBall *mb = (MetaBall *)obedit->data;
if (BKE_mball_is_any_selected(mb)) {
return true;
@ -559,64 +559,83 @@ int BKE_mball_select_count(const MetaBall *mb)
return sel;
}
int BKE_mball_select_count_multi(Object **objects, int objects_len)
int BKE_mball_select_count_multi(Base **bases, int bases_len)
{
int sel = 0;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
const Object *obedit = objects[ob_index];
for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
const Object *obedit = bases[ob_index]->object;
const MetaBall *mb = (MetaBall *)obedit->data;
sel += BKE_mball_select_count(mb);
}
return sel;
}
void BKE_mball_select_all(MetaBall *mb)
bool BKE_mball_select_all(MetaBall *mb)
{
bool changed = false;
for (MetaElem *ml = mb->editelems->first; ml; ml = ml->next) {
ml->flag |= SELECT;
if ((ml->flag & SELECT) == 0) {
ml->flag |= SELECT;
changed = true;
}
}
return changed;
}
void BKE_mball_select_all_multi(Object **objects, int objects_len)
bool BKE_mball_select_all_multi_ex(Base **bases, int bases_len)
{
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bool changed_multi = false;
for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
Object *obedit = bases[ob_index]->object;
MetaBall *mb = obedit->data;
BKE_mball_select_all(mb);
changed_multi |= BKE_mball_select_all(mb);
}
return changed_multi;
}
void BKE_mball_deselect_all(MetaBall *mb)
bool BKE_mball_deselect_all(MetaBall *mb)
{
bool changed = false;
for (MetaElem *ml = mb->editelems->first; ml; ml = ml->next) {
ml->flag &= ~SELECT;
if ((ml->flag & SELECT) != 0) {
ml->flag &= ~SELECT;
changed = true;
}
}
return changed;
}
void BKE_mball_deselect_all_multi(Object **objects, int objects_len)
bool BKE_mball_deselect_all_multi_ex(Base **bases, int bases_len)
{
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bool changed_multi = false;
for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
Object *obedit = bases[ob_index]->object;
MetaBall *mb = obedit->data;
BKE_mball_deselect_all(mb);
changed_multi |= BKE_mball_deselect_all(mb);
DEG_id_tag_update(&mb->id, ID_RECALC_SELECT);
}
return changed_multi;
}
void BKE_mball_select_swap(MetaBall *mb)
bool BKE_mball_select_swap(MetaBall *mb)
{
bool changed = false;
for (MetaElem *ml = mb->editelems->first; ml; ml = ml->next) {
ml->flag ^= SELECT;
changed = true;
}
return changed;
}
void BKE_mball_select_swap_multi(Object **objects, int objects_len)
bool BKE_mball_select_swap_multi_ex(Base **bases, int bases_len)
{
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bool changed_multi = false;
for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
Object *obedit = bases[ob_index]->object;
MetaBall *mb = (MetaBall *)obedit->data;
BKE_mball_select_swap(mb);
changed_multi |= BKE_mball_select_swap(mb);
}
return changed_multi;
}
/* **** Depsgraph evaluation **** */

View File

@ -561,46 +561,69 @@ cache_end:
return NULL;
}
void ED_armature_edit_deselect_all(Object *obedit)
bool ED_armature_edit_deselect_all(Object *obedit)
{
bArmature *arm = obedit->data;
EditBone *ebone;
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
bool changed = false;
for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (ebone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) {
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
changed = true;
}
}
return changed;
}
void ED_armature_edit_deselect_all_visible(Object *obedit)
bool ED_armature_edit_deselect_all_visible(Object *obedit)
{
bArmature *arm = obedit->data;
EditBone *ebone;
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
bool changed = false;
for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
/* first and foremost, bone must be visible and selected */
if (EBONE_VISIBLE(arm, ebone)) {
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
if (ebone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) {
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
changed = true;
}
}
}
ED_armature_edit_sync_selection(arm->edbo);
if (changed) {
ED_armature_edit_sync_selection(arm->edbo);
}
return changed;
}
void ED_armature_edit_deselect_all_multi(struct Object **objects, uint objects_len)
bool ED_armature_edit_deselect_all_multi_ex(struct Base **bases, uint bases_len)
{
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ED_armature_edit_deselect_all(obedit);
bool changed_multi = false;
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *obedit = bases[base_index]->object;
changed_multi |= ED_armature_edit_deselect_all(obedit);
}
return changed_multi;
}
void ED_armature_edit_deselect_all_visible_multi(struct Object **objects, uint objects_len)
bool ED_armature_edit_deselect_all_visible_multi_ex(struct Base **bases, uint bases_len)
{
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ED_armature_edit_deselect_all_visible(obedit);
bool changed_multi = false;
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *obedit = bases[base_index]->object;
changed_multi |= ED_armature_edit_deselect_all_visible(obedit);
}
return changed_multi;
}
bool ED_armature_edit_deselect_all_visible_multi(bContext *C)
{
ViewContext vc;
ED_view3d_viewcontext_init(C, &vc);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
}
/* accounts for connected parents */
@ -636,10 +659,10 @@ bool ED_armature_edit_select_pick(bContext *C, const int mval[2], bool extend, b
}
if (!extend && !deselect && !toggle) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &objects_len);
ED_armature_edit_deselect_all_multi(objects, objects_len);
MEM_freeN(objects);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &bases_len);
ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
}
/* by definition the non-root connected bones have no root point drawn,

View File

@ -172,10 +172,10 @@ bool ED_armature_pose_select_pick_with_buffer(
if (!extend && !deselect && !toggle) {
{
uint objects_len = 0;
Object **objects = BKE_object_pose_array_get_unique(view_layer, v3d, &objects_len);
ED_pose_deselect_all_multi(objects, objects_len, SEL_DESELECT, true);
MEM_freeN(objects);
uint bases_len = 0;
Base **bases = BKE_object_pose_base_array_get_unique(view_layer, v3d, &bases_len);
ED_pose_deselect_all_multi_ex(bases, bases_len, SEL_DESELECT, true);
MEM_freeN(bases);
}
nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
arm->act_bone = nearBone;
@ -283,10 +283,10 @@ static bool ed_pose_is_any_selected(Object *ob, bool ignore_visibility)
return false;
}
static bool ed_pose_is_any_selected_multi(Object **objects, uint objects_len, bool ignore_visibility)
static bool ed_pose_is_any_selected_multi(Base **bases, uint bases_len, bool ignore_visibility)
{
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *ob_iter = bases[base_index]->object;
if (ed_pose_is_any_selected(ob_iter, ignore_visibility)) {
return true;
}
@ -294,19 +294,34 @@ static bool ed_pose_is_any_selected_multi(Object **objects, uint objects_len, bo
return false;
}
void ED_pose_deselect_all_multi(Object **objects, uint objects_len, int select_mode, const bool ignore_visibility)
bool ED_pose_deselect_all_multi_ex(Base **bases, uint bases_len, int select_mode, const bool ignore_visibility)
{
if (select_mode == SEL_TOGGLE) {
select_mode = ed_pose_is_any_selected_multi(
objects, objects_len, ignore_visibility) ? SEL_DESELECT : SEL_SELECT;
bases, bases_len, ignore_visibility) ? SEL_DESELECT : SEL_SELECT;
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
bool changed_multi = false;
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *ob_iter = bases[base_index]->object;
if (ED_pose_deselect_all(ob_iter, select_mode, ignore_visibility)) {
ED_pose_bone_select_tag_update(ob_iter);
changed_multi = true;
}
}
return changed_multi;
}
bool ED_pose_deselect_all_multi(bContext *C, int select_mode, const bool ignore_visibility)
{
ViewContext vc;
ED_view3d_viewcontext_init(C, &vc);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_mode(vc.view_layer, vc.v3d, &bases_len, {.object_mode = OB_MODE_POSE,});
bool changed_multi = ED_pose_deselect_all_multi_ex(bases, bases_len, select_mode, ignore_visibility);
MEM_freeN(bases);
return changed_multi;
}
/* ***************** Selections ********************** */

View File

@ -784,13 +784,7 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
}
/* Deselect all existing curves. */
{
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
ED_curve_deselect_all_multi(objects, objects_len);
MEM_freeN(objects);
}
ED_curve_deselect_all_multi(C);
const float radius_min = cps->radius_min;
const float radius_max = cps->radius_max;

View File

@ -163,15 +163,18 @@ int ED_curve_nurb_select_count(View3D *v3d, Nurb *nu)
return sel;
}
void ED_curve_nurb_select_all(Nurb *nu)
bool ED_curve_nurb_select_all(const Nurb *nu)
{
bool changed = false;
int i;
if (nu->bezt) {
BezTriple *bezt;
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
if (bezt->hide == 0) {
BEZT_SEL_ALL(bezt);
if (BEZT_ISSEL_ALL(bezt) == false) {
BEZT_SEL_ALL(bezt);
changed = true;
}
}
}
}
@ -179,36 +182,48 @@ void ED_curve_nurb_select_all(Nurb *nu)
BPoint *bp;
for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
if (bp->hide == 0) {
bp->f1 |= SELECT;
if ((bp->f1 & SELECT) == 0) {
bp->f1 |= SELECT;
changed = true;
}
}
}
}
return changed;
}
void ED_curve_select_all(EditNurb *editnurb)
bool ED_curve_select_all(EditNurb *editnurb)
{
Nurb *nu;
for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
ED_curve_nurb_select_all(nu);
bool changed = false;
for (Nurb *nu = editnurb->nurbs.first; nu; nu = nu->next) {
changed |= ED_curve_nurb_select_all(nu);
}
return changed;
}
void ED_curve_nurb_deselect_all(Nurb *nu)
bool ED_curve_nurb_deselect_all(const Nurb *nu)
{
bool changed = false;
int i;
if (nu->bezt) {
BezTriple *bezt;
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
BEZT_DESEL_ALL(bezt);
if (BEZT_ISSEL_ANY(bezt)) {
BEZT_DESEL_ALL(bezt);
changed = true;
}
}
}
else if (nu->bp) {
BPoint *bp;
for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
bp->f1 &= ~SELECT;
if (bp->f1 & SELECT) {
bp->f1 &= ~SELECT;
changed = true;
}
}
}
return changed;
}
int ED_curve_select_count(View3D *v3d, struct EditNurb *editnurb)
@ -236,30 +251,45 @@ bool ED_curve_select_check(View3D *v3d, struct EditNurb *editnurb)
return false;
}
void ED_curve_deselect_all(EditNurb *editnurb)
bool ED_curve_deselect_all(EditNurb *editnurb)
{
Nurb *nu;
for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
ED_curve_nurb_deselect_all(nu);
bool changed = false;
for (Nurb *nu = editnurb->nurbs.first; nu; nu = nu->next) {
changed |= ED_curve_nurb_deselect_all(nu);
}
return changed;
}
void ED_curve_deselect_all_multi(Object **objects, int objects_len)
bool ED_curve_deselect_all_multi_ex(Base **bases, int bases_len)
{
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bool changed_multi = false;
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *obedit = bases[base_index]->object;
Curve *cu = obedit->data;
ED_curve_deselect_all(cu->editnurb);
changed_multi |= ED_curve_deselect_all(cu->editnurb);
DEG_id_tag_update(&cu->id, ID_RECALC_SELECT);
}
return changed_multi;
}
void ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
bool ED_curve_deselect_all_multi(struct bContext *C)
{
ViewContext vc;
ED_view3d_viewcontext_init(C, &vc);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = ED_curve_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
}
bool ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
{
Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
bool changed = false;
for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
@ -272,6 +302,7 @@ void ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
bezt->f1 ^= SELECT;
bezt->f3 ^= SELECT;
}
changed = true;
}
bezt++;
}
@ -280,11 +311,15 @@ void ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
while (a--) {
swap_selection_bpoint(bp);
if (bp->hide == 0) {
swap_selection_bpoint(bp);
changed = true;
}
bp++;
}
}
}
return changed;
}
/**
@ -489,7 +524,6 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@ -506,22 +540,25 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Curve *cu = obedit->data;
bool changed = false;
switch (action) {
case SEL_SELECT:
ED_curve_select_all(cu->editnurb);
changed = ED_curve_select_all(cu->editnurb);
break;
case SEL_DESELECT:
ED_curve_deselect_all(cu->editnurb);
changed = ED_curve_deselect_all(cu->editnurb);
break;
case SEL_INVERT:
ED_curve_select_swap(cu->editnurb, (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0);
changed = ED_curve_select_swap(cu->editnurb, (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0);
break;
}
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
BKE_curve_nurb_vert_active_validate(cu);
if (changed) {
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
BKE_curve_nurb_vert_active_validate(cu);
}
}
MEM_freeN(objects);
@ -567,8 +604,7 @@ static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
for (nu = nurbs->first; nu; nu = nu->next) {
if (ED_curve_nurb_select_check(v3d, nu)) {
ED_curve_nurb_select_all(nu);
changed = true;
changed |= ED_curve_nurb_select_all(nu);
}
}
@ -1634,8 +1670,7 @@ static int curve_select_similar_exec(bContext *C, wmOperator *op)
case SIMCURHAND_TYPE:
{
if (nu->type & type_ref) {
ED_curve_nurb_select_all(nu);
changed = true;
changed |= ED_curve_nurb_select_all(nu);
}
break;
}

View File

@ -154,11 +154,12 @@ void ED_armature_from_edit(struct Main *bmain, struct bArmature *arm);
void ED_armature_to_edit(struct bArmature *arm);
void ED_armature_edit_free(struct bArmature *arm);
void ED_armature_edit_deselect_all(struct Object *obedit);
void ED_armature_edit_deselect_all_visible(struct Object *obedit);
bool ED_armature_edit_deselect_all(struct Object *obedit);
bool ED_armature_edit_deselect_all_visible(struct Object *obedit);
void ED_armature_edit_deselect_all_multi(struct Object **objects, uint objects_len);
void ED_armature_edit_deselect_all_visible_multi(struct Object **objects, uint objects_len);
bool ED_armature_edit_deselect_all_multi_ex(struct Base **bases, uint bases_len);
bool ED_armature_edit_deselect_all_visible_multi_ex(struct Base **bases, uint bases_len);
bool ED_armature_edit_deselect_all_visible_multi(struct bContext *C);
bool ED_armature_pose_select_pick_with_buffer(
struct ViewLayer *view_layer, struct View3D *v3d, struct Base *base, const unsigned int *buffer, short hits,
@ -239,8 +240,9 @@ bool ED_object_posemode_exit_ex(struct Main *bmain, struct Object *ob);
bool ED_object_posemode_exit(struct bContext *C, struct Object *ob);
bool ED_object_posemode_enter_ex(struct Main *bmain, struct Object *ob);
bool ED_object_posemode_enter(struct bContext *C, struct Object *ob);
bool ED_pose_deselect_all_multi_ex(struct Base **bases, uint bases_len, int select_mode, const bool ignore_visibility);
bool ED_pose_deselect_all_multi(struct bContext *C, int select_mode, const bool ignore_visibility);
bool ED_pose_deselect_all(struct Object *ob, int select_mode, const bool ignore_visibility);
void ED_pose_deselect_all_multi(struct Object **objects, uint objects_len, int select_mode, const bool ignore_visibility);
void ED_pose_bone_select_tag_update(struct Object *ob);
void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select);
void ED_pose_recalculate_paths(struct bContext *C, struct Scene *scene, struct Object *ob, bool current_frame_only);

View File

@ -25,6 +25,7 @@
#define __ED_CURVE_H__
struct BPoint;
struct Base;
struct BezTriple;
struct Curve;
struct EditNurb;
@ -56,17 +57,18 @@ struct Nurb *ED_curve_add_nurbs_primitive(struct bContext *C, struct Object *obe
bool ED_curve_nurb_select_check(struct View3D *v3d, struct Nurb *nu);
int ED_curve_nurb_select_count(struct View3D *v3d, struct Nurb *nu);
void ED_curve_nurb_select_all(struct Nurb *nu);
void ED_curve_nurb_deselect_all(struct Nurb *nu);
bool ED_curve_nurb_select_all(const struct Nurb *nu);
bool ED_curve_nurb_deselect_all(const struct Nurb *nu);
int join_curve_exec(struct bContext *C, struct wmOperator *op);
/* editcurve_select.c */
bool ED_curve_select_check(struct View3D *v3d, struct EditNurb *editnurb);
void ED_curve_deselect_all(struct EditNurb *editnurb);
void ED_curve_deselect_all_multi(struct Object **objects, int objects_len);
void ED_curve_select_all(struct EditNurb *editnurb);
void ED_curve_select_swap(struct EditNurb *editnurb, bool hide_handles);
bool ED_curve_deselect_all(struct EditNurb *editnurb);
bool ED_curve_deselect_all_multi_ex(struct Base **bases, int bases_len);
bool ED_curve_deselect_all_multi(struct bContext *C);
bool ED_curve_select_all(struct EditNurb *editnurb);
bool ED_curve_select_swap(struct EditNurb *editnurb, bool hide_handles);
int ED_curve_select_count(struct View3D *v3d, struct EditNurb *editnurb);
/* editcurve_undo.c */

View File

@ -24,6 +24,7 @@
#ifndef __ED_LATTICE_H__
#define __ED_LATTICE_H__
struct Base;
struct Object;
struct UndoType;
struct wmKeyConfig;
@ -33,9 +34,12 @@ void ED_operatortypes_lattice(void);
void ED_keymap_lattice(struct wmKeyConfig *keyconf);
/* editlattice_select.c */
void ED_lattice_flags_set(struct Object *obedit, int flag);
bool ED_lattice_flags_set(struct Object *obedit, int flag);
bool ED_lattice_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
bool ED_lattice_deselect_all_multi_ex(struct Base **bases, const uint bases_len);
bool ED_lattice_deselect_all_multi(struct bContext *C);
/* editlattice_undo.c */
void ED_lattice_undosys_type(struct UndoType *ut);

View File

@ -24,6 +24,7 @@
#ifndef __ED_MBALL_H__
#define __ED_MBALL_H__
struct Base;
struct Object;
struct UndoType;
struct bContext;
@ -37,6 +38,9 @@ struct MetaElem *ED_mball_add_primitive(struct bContext *C, struct Object *obedi
bool ED_mball_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
bool ED_mball_deselect_all_multi_ex(struct Base **bases, uint bases_len);
bool ED_mball_deselect_all_multi(struct bContext *C);
void ED_mball_editmball_free(struct Object *obedit);
void ED_mball_editmball_make(struct Object *obedit);
void ED_mball_editmball_load(struct Object *obedit);

View File

@ -203,6 +203,9 @@ void EDBM_select_swap(struct BMEditMesh *em); /* exported for UV */
bool EDBM_select_interior_faces(struct BMEditMesh *em);
void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* rename? */
bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len);
bool EDBM_mesh_deselect_all_multi(struct bContext *C);
extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
/* editmesh_preselect_edgering.c */
@ -237,15 +240,15 @@ void EDBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct BMEd
/* editface.c */
void paintface_flush_flags(struct bContext *C, struct Object *ob, short flag);
bool paintface_mouse_select(struct bContext *C, struct Object *ob, const int mval[2], bool extend, bool deselect, bool toggle);
int do_paintface_box_select(struct ViewContext *vc, const struct rcti *rect, int sel_op);
void paintface_deselect_all_visible(struct bContext *C, struct Object *ob, int action, bool flush_flags);
bool do_paintface_box_select(struct ViewContext *vc, const struct rcti *rect, int sel_op);
bool paintface_deselect_all_visible(struct bContext *C, struct Object *ob, int action, bool flush_flags);
void paintface_select_linked(struct bContext *C, struct Object *ob, const int mval[2], const bool select);
bool paintface_minmax(struct Object *ob, float r_min[3], float r_max[3]);
void paintface_hide(struct bContext *C, struct Object *ob, const bool unselected);
void paintface_reveal(struct bContext *C, struct Object *ob, const bool select);
void paintvert_deselect_all_visible(struct Object *ob, int action, bool flush_flags);
bool paintvert_deselect_all_visible(struct Object *ob, int action, bool flush_flags);
void paintvert_select_ungrouped(struct Object *ob, bool extend, bool flush_flags);
void paintvert_flush_flags(struct Object *ob);
void paintvert_tag_select_update(struct bContext *C, struct Object *ob);

View File

@ -53,11 +53,12 @@ void PE_update_object(
struct Object *ob, int useflag);
/* selection tools */
int PE_mouse_particles(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
int PE_box_select(struct bContext *C, const struct rcti *rect, const int sel_op);
bool PE_mouse_particles(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
bool PE_box_select(struct bContext *C, const struct rcti *rect, const int sel_op);
bool PE_circle_select(struct bContext *C, int sel_op, const int mval[2], float rad);
int PE_lasso_select(struct bContext *C, const int mcords[][2], const short moves, const int sel_op);
void PE_deselect_all_visible(struct PTCacheEdit *edit);
bool PE_deselect_all_visible_ex(struct PTCacheEdit *edit);
bool PE_deselect_all_visible(struct bContext *C);
/* particle_edit_undo.c */
void ED_particle_undosys_type(struct UndoType *ut);

View File

@ -37,7 +37,7 @@ struct rcti;
/* sculpt.c */
void ED_operatortypes_sculpt(void);
void ED_sculpt_redraw_planes_get(float planes[4][4], struct ARegion *ar, struct Object *ob);
int ED_sculpt_mask_box_select(struct bContext *C, struct ViewContext *vc, const struct rcti *rect, bool select);
bool ED_sculpt_mask_box_select(struct bContext *C, struct ViewContext *vc, const struct rcti *rect, bool select);
/* sculpt_undo.c */
void ED_sculpt_undosys_type(struct UndoType *ut);

View File

@ -75,6 +75,29 @@ static void bpoint_select_set(BPoint *bp, bool select)
}
}
bool ED_lattice_deselect_all_multi_ex(struct Base **bases, const uint bases_len)
{
bool changed_multi = false;
for (uint base_index = 0; base_index < bases_len; base_index++) {
Base *base_iter = bases[base_index];
Object *ob_iter = base_iter->object;
changed_multi |= ED_lattice_flags_set(ob_iter, 0);
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
}
return changed_multi;
}
bool ED_lattice_deselect_all_multi(struct bContext *C)
{
ViewContext vc;
ED_view3d_viewcontext_init(C, &vc);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = ED_lattice_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
}
/** \} */
/* -------------------------------------------------------------------- */
@ -356,23 +379,32 @@ void LATTICE_OT_select_less(wmOperatorType *ot)
/** \name Select All Operator
* \{ */
void ED_lattice_flags_set(Object *obedit, int flag)
bool ED_lattice_flags_set(Object *obedit, int flag)
{
Lattice *lt = obedit->data;
BPoint *bp;
int a;
bool changed = false;
bp = lt->editlatt->latt->def;
a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
lt->editlatt->latt->actbp = LT_ACTBP_NONE;
if (lt->editlatt->latt->actbp != LT_ACTBP_NONE) {
lt->editlatt->latt->actbp = LT_ACTBP_NONE;
changed = true;
}
while (a--) {
if (bp->hide == 0) {
bp->f1 = flag;
if (bp->f1 != flag) {
bp->f1 = flag;
changed = true;
}
}
bp++;
}
return changed;
}
static int lattice_select_all_exec(bContext *C, wmOperator *op)
@ -395,18 +427,20 @@ static int lattice_select_all_exec(bContext *C, wmOperator *op)
}
}
bool changed_multi = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Lattice *lt;
BPoint *bp;
int a;
bool changed = false;
switch (action) {
case SEL_SELECT:
ED_lattice_flags_set(obedit, 1);
changed = ED_lattice_flags_set(obedit, 1);
break;
case SEL_DESELECT:
ED_lattice_flags_set(obedit, 0);
changed = ED_lattice_flags_set(obedit, 0);
break;
case SEL_INVERT:
lt = obedit->data;
@ -417,18 +451,24 @@ static int lattice_select_all_exec(bContext *C, wmOperator *op)
while (a--) {
if (bp->hide == 0) {
bp->f1 ^= SELECT;
changed = true;
}
bp++;
}
break;
}
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
if (changed) {
changed_multi = true;
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
}
MEM_freeN(objects);
return OPERATOR_FINISHED;
if (changed_multi) {
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
void LATTICE_OT_select_all(wmOperatorType *ot)
@ -597,10 +637,10 @@ bool ED_lattice_select_pick(bContext *C, const int mval[2], bool extend, bool de
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
ED_lattice_flags_set(ob, 0);
DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
if (ED_lattice_flags_set(ob, 0)) {
DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
}
}
MEM_freeN(objects);
}

View File

@ -282,14 +282,16 @@ void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const b
paintface_flush_flags(C, ob, SELECT);
}
void paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool flush_flags)
bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool flush_flags)
{
Mesh *me;
MPoly *mpoly;
int a;
me = BKE_mesh_from_object(ob);
if (me == NULL) return;
if (me == NULL) {
return false;
}
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
@ -305,28 +307,40 @@ void paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
}
}
bool changed = false;
mpoly = me->mpoly;
a = me->totpoly;
while (a--) {
if ((mpoly->flag & ME_HIDE) == 0) {
switch (action) {
case SEL_SELECT:
mpoly->flag |= ME_FACE_SEL;
if ((mpoly->flag & ME_FACE_SEL) == 0) {
mpoly->flag |= ME_FACE_SEL;
changed = true;
}
break;
case SEL_DESELECT:
mpoly->flag &= ~ME_FACE_SEL;
if ((mpoly->flag & ME_FACE_SEL) != 0) {
mpoly->flag &= ~ME_FACE_SEL;
changed = true;
}
break;
case SEL_INVERT:
mpoly->flag ^= ME_FACE_SEL;
changed = true;
break;
}
}
mpoly++;
}
if (flush_flags) {
paintface_flush_flags(C, ob, SELECT);
if (changed) {
if (flush_flags) {
paintface_flush_flags(C, ob, SELECT);
}
}
return changed;
}
bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
@ -389,10 +403,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b
mpoly = me->mpoly;
a = me->totpoly;
if (!extend && !deselect && !toggle) {
while (a--) {
mpoly->flag &= ~ME_FACE_SEL;
mpoly++;
}
paintface_deselect_all_visible(C, ob, SEL_DESELECT, false);
}
me->act_face = (int)index;
@ -420,7 +431,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b
return true;
}
int do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
bool do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
{
Object *ob = vc->obact;
Mesh *me;
@ -431,13 +442,14 @@ int do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
me = BKE_mesh_from_object(ob);
if ((me == NULL) || (me->totpoly == 0) || BLI_rcti_is_empty(rect)) {
return OPERATOR_CANCELLED;
return false;
}
selar = MEM_callocN(me->totpoly + 1, "selar");
bool changed = false;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false);
changed |= paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false);
}
uint buf_len;
@ -464,6 +476,7 @@ int do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
changed = true;
}
}
}
@ -475,9 +488,10 @@ int do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
glReadBuffer(GL_BACK);
#endif
paintface_flush_flags(vc->C, vc->obact, SELECT);
return OPERATOR_FINISHED;
if (changed) {
paintface_flush_flags(vc->C, vc->obact, SELECT);
}
return changed;
}
@ -536,14 +550,16 @@ void paintvert_tag_select_update(struct bContext *C, struct Object *ob)
/* note: if the caller passes false to flush_flags,
* then they will need to run paintvert_flush_flags(ob) themselves */
void paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
{
Mesh *me;
MVert *mvert;
int a;
me = BKE_mesh_from_object(ob);
if (me == NULL) return;
if (me == NULL) {
return false;
}
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
@ -559,39 +575,50 @@ void paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
}
}
bool changed = false;
mvert = me->mvert;
a = me->totvert;
while (a--) {
if ((mvert->flag & ME_HIDE) == 0) {
switch (action) {
case SEL_SELECT:
mvert->flag |= SELECT;
if ((mvert->flag & SELECT) == 0) {
mvert->flag |= SELECT;
changed = true;
}
break;
case SEL_DESELECT:
mvert->flag &= ~SELECT;
if ((mvert->flag & SELECT) != 0) {
mvert->flag &= ~SELECT;
changed = true;
}
break;
case SEL_INVERT:
mvert->flag ^= SELECT;
changed = true;
break;
}
}
mvert++;
}
/* handle mselect */
if (action == SEL_SELECT) {
/* pass */
}
else if (ELEM(action, SEL_DESELECT, SEL_INVERT)) {
BKE_mesh_mselect_clear(me);
}
else {
BKE_mesh_mselect_validate(me);
}
if (changed) {
/* handle mselect */
if (action == SEL_SELECT) {
/* pass */
}
else if (ELEM(action, SEL_DESELECT, SEL_INVERT)) {
BKE_mesh_mselect_clear(me);
}
else {
BKE_mesh_mselect_validate(me);
}
if (flush_flags) {
paintvert_flush_flags(ob);
if (flush_flags) {
paintvert_flush_flags(ob);
}
}
return changed;
}
void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)

View File

@ -2597,6 +2597,36 @@ void EDBM_select_swap(BMEditMesh *em) /* exported for UV */
}
}
bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len)
{
bool changed_multi = false;
for (uint base_index = 0; base_index < bases_len; base_index++) {
Base *base_iter = bases[base_index];
Object *ob_iter = base_iter->object;
BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
if (em_iter->bm->totvertsel == 0) {
continue;
}
EDBM_flag_disable_all(em_iter, BM_ELEM_SELECT);
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
changed_multi = true;
}
return changed_multi;
}
bool EDBM_mesh_deselect_all_multi(struct bContext *C)
{
ViewContext vc;
ED_view3d_viewcontext_init(C, &vc);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = EDBM_mesh_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -125,35 +125,35 @@ static int mball_select_all_exec(bContext *C, wmOperator *op)
int action = RNA_enum_get(op->ptr, "action");
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &bases_len);
if (action == SEL_TOGGLE) {
action = BKE_mball_is_any_selected_multi(objects, objects_len) ?
action = BKE_mball_is_any_selected_multi(bases, bases_len) ?
SEL_DESELECT :
SEL_SELECT;
}
switch (action) {
case SEL_SELECT:
BKE_mball_select_all_multi(objects, objects_len);
BKE_mball_select_all_multi_ex(bases, bases_len);
break;
case SEL_DESELECT:
BKE_mball_deselect_all_multi(objects, objects_len);
BKE_mball_deselect_all_multi_ex(bases, bases_len);
break;
case SEL_INVERT:
BKE_mball_select_swap_multi(objects, objects_len);
BKE_mball_select_swap_multi_ex(bases, bases_len);
break;
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *obedit = bases[base_index]->object;
MetaBall *mb = (MetaBall *)obedit->data;
DEG_id_tag_update(&mb->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);
}
MEM_freeN(objects);
MEM_freeN(bases);
return OPERATOR_FINISHED;
}
@ -315,10 +315,10 @@ static int mball_select_similar_exec(bContext *C, wmOperator *op)
int tot_mball_selected_all = 0;
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &bases_len);
tot_mball_selected_all = BKE_mball_select_count_multi(objects, objects_len);
tot_mball_selected_all = BKE_mball_select_count_multi(bases, bases_len);
short type_ref = 0;
KDTree_1d *tree_1d = NULL;
@ -335,8 +335,8 @@ static int mball_select_similar_exec(bContext *C, wmOperator *op)
}
/* Get type of selected MetaBall */
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *obedit = bases[base_index]->object;
MetaBall *mb = (MetaBall *)obedit->data;
switch (type) {
@ -371,8 +371,8 @@ static int mball_select_similar_exec(bContext *C, wmOperator *op)
BLI_kdtree_3d_balance(tree_3d);
}
/* Select MetaBalls with desired type. */
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
for (uint base_index = 0; base_index < bases_len; base_index++) {
Object *obedit = bases[base_index]->object;
MetaBall *mb = (MetaBall *)obedit->data;
bool changed = false;
@ -405,7 +405,7 @@ static int mball_select_similar_exec(bContext *C, wmOperator *op)
}
}
MEM_freeN(objects);
MEM_freeN(bases);
if (tree_1d != NULL) {
BLI_kdtree_1d_free(tree_1d);
}
@ -821,3 +821,14 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
return false;
}
bool ED_mball_deselect_all_multi(bContext *C)
{
ViewContext vc;
ED_view3d_viewcontext_init(C, &vc);
uint bases_len = 0;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &bases_len);
bool changed_multi = BKE_mball_deselect_all_multi_ex(bases, bases_len);
MEM_freeN(bases);
return changed_multi;
}

View File

@ -496,7 +496,7 @@ static void PE_free_random_generator(PEData *data)
/*************************** selection utilities *******************************/
static bool key_test_depth(PEData *data, const float co[3], const int screen_co[2])
static bool key_test_depth(const PEData *data, const float co[3], const int screen_co[2])
{
View3D *v3d = data->vc.v3d;
ViewDepths *vd = data->vc.rv3d->depths;
@ -533,7 +533,7 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
return 1;
}
static bool key_inside_circle(PEData *data, float rad, const float co[3], float *distance)
static bool key_inside_circle(const PEData *data, float rad, const float co[3], float *distance)
{
float dx, dy, dist;
int screen_co[2];
@ -1562,6 +1562,7 @@ static void select_key_op(PEData *data, int point_index, int key_index, bool is_
if (sel_op_result != -1) {
SET_FLAG_FROM_TEST(key->flag, sel_op_result, PEK_SELECT);
point->flag |= PEP_EDIT_RECALC;
data->is_changed = true;
}
}
@ -1587,8 +1588,11 @@ static void extend_key_select(PEData *data, int point_index, int key_index, bool
PTCacheEditPoint *point = edit->points + point_index;
PTCacheEditKey *key = point->keys + key_index;
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
if ((key->flag & PEK_SELECT) == 0) {
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
data->is_changed = true;
}
}
static void deselect_key_select(PEData *data, int point_index, int key_index, bool UNUSED(is_inside))
@ -1597,8 +1601,11 @@ static void deselect_key_select(PEData *data, int point_index, int key_index, bo
PTCacheEditPoint *point = edit->points + point_index;
PTCacheEditKey *key = point->keys + key_index;
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
if ((key->flag & PEK_SELECT) != 0) {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
data->is_changed = true;
}
}
static void toggle_key_select(PEData *data, int point_index, int key_index, bool UNUSED(is_inside))
@ -1609,36 +1616,43 @@ static void toggle_key_select(PEData *data, int point_index, int key_index, bool
key->flag ^= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
data->is_changed = true;
}
/************************ de select all operator ************************/
static void select_action_apply(PTCacheEditPoint *point, PTCacheEditKey *key, int action)
static bool select_action_apply(PTCacheEditPoint *point, PTCacheEditKey *key, int action)
{
bool changed = false;
switch (action) {
case SEL_SELECT:
if ((key->flag & PEK_SELECT) == 0) {
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
changed = true;
}
break;
case SEL_DESELECT:
if (key->flag & PEK_SELECT) {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
changed = true;
}
break;
case SEL_INVERT:
if ((key->flag & PEK_SELECT) == 0) {
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
changed = true;
}
else {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
changed = true;
}
break;
}
return changed;
}
static int pe_select_all_exec(bContext *C, wmOperator *op)
@ -1663,15 +1677,17 @@ static int pe_select_all_exec(bContext *C, wmOperator *op)
}
}
bool changed = false;
LOOP_VISIBLE_POINTS {
LOOP_VISIBLE_KEYS {
select_action_apply(point, key, action);
changed |= select_action_apply(point, key, action);
}
}
PE_update_selection(depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
if (changed) {
PE_update_selection(depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
}
return OPERATOR_FINISHED;
}
@ -1694,7 +1710,7 @@ void PARTICLE_OT_select_all(wmOperatorType *ot)
/************************ pick select operator ************************/
int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
bool PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
{
PEData data;
Scene *scene = CTX_data_scene(C);
@ -1702,8 +1718,9 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec
PTCacheEdit *edit = PE_get_current(scene, ob);
POINT_P; KEY_K;
if (!PE_start_edit(edit))
return OPERATOR_CANCELLED;
if (!PE_start_edit(edit)) {
return false;
}
if (!extend && !deselect && !toggle) {
LOOP_VISIBLE_POINTS {
@ -1729,10 +1746,12 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec
for_mouse_hit_keys(&data, toggle_key_select, PSEL_NEAREST);
}
PE_update_selection(data.depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
if (data.is_changed) {
PE_update_selection(data.depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
}
return OPERATOR_FINISHED;
return true;
}
/************************ select root operator ************************/
@ -1745,10 +1764,12 @@ static void select_root(PEData *data, int point_index)
if (point->flag & PEP_HIDE)
return;
if (data->select_action != SEL_TOGGLE)
select_action_apply(point, key, data->select_action);
else if (key->flag & PEK_SELECT)
if (data->select_action != SEL_TOGGLE) {
data->is_changed = select_action_apply(point, key, data->select_action);
}
else if (key->flag & PEK_SELECT) {
data->select_toggle_action = SEL_DESELECT;
}
}
static int select_roots_exec(bContext *C, wmOperator *op)
@ -1770,9 +1791,10 @@ static int select_roots_exec(bContext *C, wmOperator *op)
data.select_action = action;
foreach_point(&data, select_root);
PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
if (data.is_changed) {
PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
}
return OPERATOR_FINISHED;
}
@ -1810,10 +1832,12 @@ static void select_tip(PEData *data, int point_index)
if (point->flag & PEP_HIDE)
return;
if (data->select_action != SEL_TOGGLE)
select_action_apply(point, key, data->select_action);
else if (key->flag & PEK_SELECT)
if (data->select_action != SEL_TOGGLE) {
data->is_changed = select_action_apply(point, key, data->select_action);
}
else if (key->flag & PEK_SELECT) {
data->select_toggle_action = SEL_DESELECT;
}
}
static int select_tips_exec(bContext *C, wmOperator *op)
@ -1835,10 +1859,13 @@ static int select_tips_exec(bContext *C, wmOperator *op)
data.select_action = action;
foreach_point(&data, select_tip);
PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
if (data.is_changed) {
PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
return OPERATOR_FINISHED;
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
void PARTICLE_OT_select_tips(wmOperatorType *ot)
@ -1899,7 +1926,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
LOOP_VISIBLE_POINTS {
int flag = ((BLI_rng_get_float(rng) < randfac) == select) ? SEL_SELECT : SEL_DESELECT;
LOOP_KEYS {
select_action_apply(point, key, flag);
data.is_changed = select_action_apply(point, key, flag);
}
}
break;
@ -1907,7 +1934,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
LOOP_VISIBLE_POINTS {
LOOP_VISIBLE_KEYS {
int flag = ((BLI_rng_get_float(rng) < randfac) == select) ? SEL_SELECT : SEL_DESELECT;
select_action_apply(point, key, flag);
data.is_changed = select_action_apply(point, key, flag);
}
}
break;
@ -1915,9 +1942,10 @@ static int select_random_exec(bContext *C, wmOperator *op)
BLI_rng_free(rng);
PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
if (data.is_changed) {
PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
}
return OPERATOR_FINISHED;
}
@ -1992,42 +2020,58 @@ void PARTICLE_OT_select_linked(wmOperatorType *ot)
}
/************************ box select operator ************************/
void PE_deselect_all_visible(PTCacheEdit *edit)
bool PE_deselect_all_visible_ex(PTCacheEdit *edit)
{
bool changed = false;
POINT_P; KEY_K;
LOOP_VISIBLE_POINTS {
LOOP_SELECTED_KEYS {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
if ((key->flag & PEK_SELECT) != 0) {
key->flag &= ~PEK_SELECT;
point->flag |= PEP_EDIT_RECALC;
changed = true;
}
}
}
return changed;
}
int PE_box_select(bContext *C, const rcti *rect, const int sel_op)
bool PE_deselect_all_visible(bContext *C)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
PTCacheEdit *edit = PE_get_current(scene, ob);
if (!PE_start_edit(edit)) {
return false;
}
return PE_deselect_all_visible_ex(edit);
}
bool PE_box_select(bContext *C, const rcti *rect, const int sel_op)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
PTCacheEdit *edit = PE_get_current(scene, ob);
PEData data;
if (!PE_start_edit(edit))
return OPERATOR_CANCELLED;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
PE_deselect_all_visible(edit);
if (!PE_start_edit(edit)) {
return false;
}
PE_set_view3d_data(C, &data);
data.rect = rect;
data.sel_op = sel_op;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
data.is_changed = PE_deselect_all_visible_ex(edit);
}
for_mouse_hit_keys(&data, select_key_op, PSEL_ALL_KEYS);
PE_update_selection(data.depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
return OPERATOR_FINISHED;
if (data.is_changed) {
PE_update_selection(data.depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
}
return data.is_changed;
}
/************************ circle select operator ************************/
@ -2044,11 +2088,6 @@ bool PE_circle_select(bContext *C, const int sel_op, const int mval[2], float ra
return false;
}
bool changed = false;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
PE_deselect_all_visible(edit);
changed = true;
}
const bool select = (sel_op != SEL_OP_SUB);
PE_set_view3d_data(C, &data);
@ -2056,14 +2095,15 @@ bool PE_circle_select(bContext *C, const int sel_op, const int mval[2], float ra
data.rad = rad;
data.select = select;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
data.is_changed = PE_deselect_all_visible_ex(edit);
}
for_mouse_hit_keys(&data, select_key, 0);
changed |= data.is_changed;
if (changed) {
if (data.is_changed) {
PE_update_selection(data.depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
}
return changed;
return data.is_changed;
}
/************************ lasso select operator ************************/
@ -2088,13 +2128,13 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, const
if (!PE_start_edit(edit))
return OPERATOR_CANCELLED;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
PE_deselect_all_visible(edit);
}
/* only for depths */
PE_set_view3d_data(C, &data);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
data.is_changed |= PE_deselect_all_visible_ex(edit);
}
LOOP_VISIBLE_POINTS {
if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR))
psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat);
@ -2112,6 +2152,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, const
if (sel_op_result != -1) {
SET_FLAG_FROM_TEST(key->flag, sel_op_result, PEK_SELECT);
point->flag |= PEP_EDIT_RECALC;
data.is_changed = true;
}
}
}
@ -2129,15 +2170,18 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, const
if (sel_op_result != -1) {
SET_FLAG_FROM_TEST(key->flag, sel_op_result, PEK_SELECT);
point->flag |= PEP_EDIT_RECALC;
data.is_changed = true;
}
}
}
}
PE_update_selection(data.depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
return OPERATOR_FINISHED;
if (data.is_changed) {
PE_update_selection(data.depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
/*************************** hide operator **************************/
@ -2267,9 +2311,10 @@ static void select_less_keys(PEData *data, int point_index)
}
LOOP_KEYS {
if (key->flag & PEK_TAG) {
if ((key->flag & PEK_TAG) && (key->flag & PEK_SELECT)) {
key->flag &= ~(PEK_TAG | PEK_SELECT);
point->flag |= PEP_EDIT_RECALC; /* redraw selection only */
data->is_changed = true;
}
}
}
@ -2328,10 +2373,11 @@ static void select_more_keys(PEData *data, int point_index)
}
LOOP_KEYS {
if (key->flag & PEK_TAG) {
if ((key->flag & PEK_TAG) && (key->flag & PEK_SELECT) == 0) {
key->flag &= ~PEK_TAG;
key->flag |= PEK_SELECT;
point->flag |= PEP_EDIT_RECALC; /* redraw selection only */
data->is_changed = true;
}
}
}

View File

@ -249,7 +249,7 @@ static void mask_box_select_task_cb(
} BKE_pbvh_vertex_iter_end;
}
int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select)
bool ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Sculpt *sd = vc->scene->toolsettings->sculpt;
@ -321,7 +321,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
return true;
}
typedef struct LassoMaskData {

View File

@ -650,9 +650,11 @@ void PAINT_OT_face_select_linked_pick(wmOperatorType *ot)
static int face_select_all_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
paintface_deselect_all_visible(C, ob, RNA_enum_get(op->ptr, "action"), true);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
if (paintface_deselect_all_visible(C, ob, RNA_enum_get(op->ptr, "action"), true)) {
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}

File diff suppressed because it is too large Load Diff

View File

@ -490,6 +490,10 @@ typedef enum eBezTriple_KeyframeType {
/* checks if the given BezTriple is selected */
#define BEZT_ISSEL_ANY(bezt) \
(((bezt)->f2 & SELECT) || ((bezt)->f1 & SELECT) || ((bezt)->f3 & SELECT))
#define BEZT_ISSEL_ALL(bezt) \
(((bezt)->f2 & SELECT) && ((bezt)->f1 & SELECT) && ((bezt)->f3 & SELECT))
#define BEZT_ISSEL_ALL_HIDDENHANDLES(v3d, bezt) \
((((v3d) != NULL) && ((v3d)->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) ? (bezt)->f2 & SELECT : BEZT_ISSEL_ALL(bezt))
#define BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt) \
((((v3d) != NULL) && ((v3d)->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) ? (bezt)->f2 & SELECT : BEZT_ISSEL_ANY(bezt))