View 3D: move picking arguments into a struct & minor refactor
- Add SelectPick_Params struct to make picking logic more straightforward and easier to extend. - Use `eSelectOp` instead of booleans (extend, deselect, toggle) which were used to represent 4 states (which wasn't obvious). - Handle deselect_all when pocking instead of view3d_select_exec, de-duplicate de-selection which was already needed in when replacing the selection in picking functions. - Handle outliner update & notifiers in the picking functions instead of view3d_select_exec. - Fix particle select deselect_all option which did nothing.
This commit is contained in:
@@ -951,127 +951,174 @@ bool ED_armature_edit_select_pick_bone(bContext *C,
|
|||||||
Base *basact,
|
Base *basact,
|
||||||
EditBone *ebone,
|
EditBone *ebone,
|
||||||
const int selmask,
|
const int selmask,
|
||||||
const bool extend,
|
const struct SelectPick_Params *params)
|
||||||
const bool deselect,
|
|
||||||
const bool toggle)
|
|
||||||
{
|
{
|
||||||
if (!ebone) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
View3D *v3d = CTX_wm_view3d(C);
|
View3D *v3d = CTX_wm_view3d(C);
|
||||||
|
bool changed = false;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
BLI_assert(BKE_object_is_in_editmode(basact->object));
|
if (ebone) {
|
||||||
bArmature *arm = basact->object->data;
|
bArmature *arm = basact->object->data;
|
||||||
|
if (EBONE_SELECTABLE(arm, ebone)) {
|
||||||
if (!EBONE_SELECTABLE(arm, ebone)) {
|
found = true;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extend && !deselect && !toggle) {
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
|
/* Deselect everything. */
|
||||||
uint bases_len = 0;
|
uint bases_len = 0;
|
||||||
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
|
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
|
||||||
view_layer, v3d, &bases_len);
|
view_layer, v3d, &bases_len);
|
||||||
ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
|
ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
|
||||||
MEM_freeN(bases);
|
MEM_freeN(bases);
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* By definition the non-root connected bones have no root point drawn,
|
if (found) {
|
||||||
* so a root selection needs to be delivered to the parent tip. */
|
BLI_assert(BKE_object_is_in_editmode(basact->object));
|
||||||
|
bArmature *arm = basact->object->data;
|
||||||
|
|
||||||
if (selmask & BONE_SELECTED) {
|
/* By definition the non-root connected bones have no root point drawn,
|
||||||
if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
|
* so a root selection needs to be delivered to the parent tip. */
|
||||||
/* Bone is in a chain. */
|
|
||||||
if (extend) {
|
if (selmask & BONE_SELECTED) {
|
||||||
/* Select this bone. */
|
if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
|
||||||
ebone->flag |= BONE_TIPSEL;
|
|
||||||
ebone->parent->flag |= BONE_TIPSEL;
|
/* Bone is in a chain. */
|
||||||
}
|
switch (params->sel_op) {
|
||||||
else if (deselect) {
|
case SEL_OP_ADD: {
|
||||||
/* Deselect this bone. */
|
/* Select this bone. */
|
||||||
ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
|
ebone->flag |= BONE_TIPSEL;
|
||||||
/* Only deselect parent tip if it is not selected. */
|
ebone->parent->flag |= BONE_TIPSEL;
|
||||||
if (!(ebone->parent->flag & BONE_SELECTED)) {
|
break;
|
||||||
ebone->parent->flag &= ~BONE_TIPSEL;
|
}
|
||||||
}
|
case SEL_OP_SUB: {
|
||||||
}
|
/* Deselect this bone. */
|
||||||
else if (toggle) {
|
ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
|
||||||
/* Toggle inverts this bone's selection. */
|
/* Only deselect parent tip if it is not selected. */
|
||||||
if (ebone->flag & BONE_SELECTED) {
|
if (!(ebone->parent->flag & BONE_SELECTED)) {
|
||||||
/* Deselect this bone. */
|
ebone->parent->flag &= ~BONE_TIPSEL;
|
||||||
ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
|
}
|
||||||
/* Only deselect parent tip if it is not selected. */
|
break;
|
||||||
if (!(ebone->parent->flag & BONE_SELECTED)) {
|
}
|
||||||
ebone->parent->flag &= ~BONE_TIPSEL;
|
case SEL_OP_XOR: {
|
||||||
|
/* Toggle inverts this bone's selection. */
|
||||||
|
if (ebone->flag & BONE_SELECTED) {
|
||||||
|
/* Deselect this bone. */
|
||||||
|
ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
|
||||||
|
/* Only deselect parent tip if it is not selected. */
|
||||||
|
if (!(ebone->parent->flag & BONE_SELECTED)) {
|
||||||
|
ebone->parent->flag &= ~BONE_TIPSEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Select this bone. */
|
||||||
|
ebone->flag |= BONE_TIPSEL;
|
||||||
|
ebone->parent->flag |= BONE_TIPSEL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
/* Select this bone. */
|
||||||
|
ebone->flag |= BONE_TIPSEL;
|
||||||
|
ebone->parent->flag |= BONE_TIPSEL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
/* Select this bone. */
|
|
||||||
ebone->flag |= BONE_TIPSEL;
|
|
||||||
ebone->parent->flag |= BONE_TIPSEL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Select this bone. */
|
switch (params->sel_op) {
|
||||||
ebone->flag |= BONE_TIPSEL;
|
case SEL_OP_ADD: {
|
||||||
ebone->parent->flag |= BONE_TIPSEL;
|
ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SUB: {
|
||||||
|
ebone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
/* Toggle inverts this bone's selection. */
|
||||||
|
if (ebone->flag & BONE_SELECTED) {
|
||||||
|
ebone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (extend) {
|
switch (params->sel_op) {
|
||||||
ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
|
case SEL_OP_ADD: {
|
||||||
}
|
ebone->flag |= selmask;
|
||||||
else if (deselect) {
|
break;
|
||||||
ebone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
|
|
||||||
}
|
|
||||||
else if (toggle) {
|
|
||||||
/* Toggle inverts this bone's selection. */
|
|
||||||
if (ebone->flag & BONE_SELECTED) {
|
|
||||||
ebone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
|
|
||||||
}
|
}
|
||||||
else {
|
case SEL_OP_SUB: {
|
||||||
ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
|
ebone->flag &= ~selmask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
if (ebone->flag & selmask) {
|
||||||
|
ebone->flag &= ~selmask;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ebone->flag |= selmask;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
ebone->flag |= selmask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
ebone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
ED_armature_edit_sync_selection(arm->edbo);
|
||||||
if (extend) {
|
|
||||||
ebone->flag |= selmask;
|
/* Then now check for active status. */
|
||||||
|
if (ED_armature_ebone_selectflag_get(ebone)) {
|
||||||
|
arm->act_edbone = ebone;
|
||||||
}
|
}
|
||||||
else if (deselect) {
|
|
||||||
ebone->flag &= ~selmask;
|
if (view_layer->basact != basact) {
|
||||||
}
|
ED_object_base_activate(C, basact);
|
||||||
else if (toggle && (ebone->flag & selmask)) {
|
|
||||||
ebone->flag &= ~selmask;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ebone->flag |= selmask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
|
||||||
|
DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ED_armature_edit_sync_selection(arm->edbo);
|
if (changed) {
|
||||||
|
ED_outliner_select_sync_from_edit_bone_tag(C);
|
||||||
/* Then now check for active status. */
|
|
||||||
if (ED_armature_ebone_selectflag_get(ebone)) {
|
|
||||||
arm->act_edbone = ebone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view_layer->basact != basact) {
|
return changed || found;
|
||||||
ED_object_base_activate(C, basact);
|
|
||||||
}
|
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
|
|
||||||
DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ED_armature_edit_select_pick(
|
bool ED_armature_edit_select_pick(bContext *C,
|
||||||
bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params)
|
||||||
|
|
||||||
{
|
{
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
ViewContext vc;
|
ViewContext vc;
|
||||||
@@ -1084,7 +1131,7 @@ bool ED_armature_edit_select_pick(
|
|||||||
vc.mval[1] = mval[1];
|
vc.mval[1] = mval[1];
|
||||||
|
|
||||||
nearBone = get_nearest_editbonepoint(&vc, true, true, &basact, &selmask);
|
nearBone = get_nearest_editbonepoint(&vc, true, true, &basact, &selmask);
|
||||||
return ED_armature_edit_select_pick_bone(C, basact, nearBone, selmask, extend, deselect, toggle);
|
return ED_armature_edit_select_pick_bone(C, basact, nearBone, selmask, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|||||||
@@ -121,104 +121,120 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
|
bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
|
||||||
View3D *v3d,
|
View3D *v3d,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
Bone *bone,
|
Bone *bone,
|
||||||
const bool extend,
|
const struct SelectPick_Params *params)
|
||||||
const bool deselect,
|
|
||||||
const bool toggle)
|
|
||||||
{
|
{
|
||||||
if (!ob || !ob->pose) {
|
bool found = false;
|
||||||
return;
|
bool changed = false;
|
||||||
}
|
|
||||||
|
|
||||||
Object *ob_act = OBACT(view_layer);
|
if (ob || ob->pose) {
|
||||||
BLI_assert(OBEDIT_FROM_VIEW_LAYER(view_layer) == NULL);
|
if (bone && ((bone->flag & BONE_UNSELECTABLE) == 0)) {
|
||||||
|
found = true;
|
||||||
/* If the bone cannot be affected, don't do anything. */
|
|
||||||
if (bone == NULL || (bone->flag & BONE_UNSELECTABLE)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bArmature *arm = ob->data;
|
|
||||||
|
|
||||||
/* Since we do unified select, we don't shift+select a bone if the
|
|
||||||
* armature object was not active yet.
|
|
||||||
* NOTE(campbell): special exception for armature mode so we can do multi-select
|
|
||||||
* we could check for multi-select explicitly but think its fine to
|
|
||||||
* always give predictable behavior in weight paint mode. */
|
|
||||||
if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) == 0)) {
|
|
||||||
/* When we are entering into posemode via toggle-select,
|
|
||||||
* from another active object - always select the bone. */
|
|
||||||
if (!extend && !deselect && toggle) {
|
|
||||||
/* Re-select the bone again later in this function. */
|
|
||||||
bone->flag &= ~BONE_SELECTED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extend && !deselect && !toggle) {
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
{
|
/* Don't use 'BKE_object_pose_base_array_get_unique'
|
||||||
/* Don't use 'BKE_object_pose_base_array_get_unique'
|
* because we may be selecting from object mode. */
|
||||||
* because we may be selecting from object mode. */
|
FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
|
||||||
FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
|
Object *ob_iter = base_iter->object;
|
||||||
Object *ob_iter = base_iter->object;
|
if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
|
||||||
if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
|
if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
|
||||||
if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
|
ED_pose_bone_select_tag_update(ob_iter);
|
||||||
ED_pose_bone_select_tag_update(ob_iter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FOREACH_VISIBLE_BASE_END;
|
|
||||||
}
|
}
|
||||||
bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
FOREACH_VISIBLE_BASE_END;
|
||||||
arm->act_bone = bone;
|
changed = true;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (extend) {
|
if (found) {
|
||||||
bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
Object *ob_act = OBACT(view_layer);
|
||||||
arm->act_bone = bone;
|
BLI_assert(OBEDIT_FROM_VIEW_LAYER(view_layer) == NULL);
|
||||||
}
|
|
||||||
else if (deselect) {
|
/* If the bone cannot be affected, don't do anything. */
|
||||||
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
bArmature *arm = ob->data;
|
||||||
}
|
|
||||||
else if (toggle) {
|
/* Since we do unified select, we don't shift+select a bone if the
|
||||||
if (bone->flag & BONE_SELECTED) {
|
* armature object was not active yet.
|
||||||
/* If not active, we make it active. */
|
* NOTE(campbell): special exception for armature mode so we can do multi-select
|
||||||
if (bone != arm->act_bone) {
|
* we could check for multi-select explicitly but think its fine to
|
||||||
arm->act_bone = bone;
|
* always give predictable behavior in weight paint mode. */
|
||||||
}
|
if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) == 0)) {
|
||||||
else {
|
/* When we are entering into posemode via toggle-select,
|
||||||
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
* from another active object - always select the bone. */
|
||||||
}
|
if (params->sel_op == SEL_OP_SET) {
|
||||||
|
/* Re-select the bone again later in this function. */
|
||||||
|
bone->flag &= ~BONE_SELECTED;
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
|
|
||||||
|
switch (params->sel_op) {
|
||||||
|
case SEL_OP_ADD: {
|
||||||
bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
arm->act_bone = bone;
|
arm->act_bone = bone;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SUB: {
|
||||||
|
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
if (bone->flag & BONE_SELECTED) {
|
||||||
|
/* If not active, we make it active. */
|
||||||
|
if (bone != arm->act_bone) {
|
||||||
|
arm->act_bone = bone;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
arm->act_bone = bone;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
bone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
||||||
|
arm->act_bone = bone;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (ob_act) {
|
if (ob_act) {
|
||||||
/* In weightpaint we select the associated vertex group too. */
|
/* In weightpaint we select the associated vertex group too. */
|
||||||
if (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) {
|
if (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) {
|
||||||
if (bone == arm->act_bone) {
|
if (bone == arm->act_bone) {
|
||||||
ED_vgroup_select_by_name(ob_act, bone->name);
|
ED_vgroup_select_by_name(ob_act, bone->name);
|
||||||
DEG_id_tag_update(&ob_act->id, ID_RECALC_GEOMETRY);
|
DEG_id_tag_update(&ob_act->id, ID_RECALC_GEOMETRY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
/* If there are some dependencies for visualizing armature state
|
||||||
/* If there are some dependencies for visualizing armature state
|
* (e.g. Mask Modifier in 'Armature' mode), force update.
|
||||||
* (e.g. Mask Modifier in 'Armature' mode), force update.
|
|
||||||
*/
|
|
||||||
else if (arm->flag & ARM_HAS_VIZ_DEPS) {
|
|
||||||
/* NOTE: ob not ob_act here is intentional - it's the source of the
|
|
||||||
* bones being selected [T37247]
|
|
||||||
*/
|
*/
|
||||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
else if (arm->flag & ARM_HAS_VIZ_DEPS) {
|
||||||
|
/* NOTE: ob not ob_act here is intentional - it's the source of the
|
||||||
|
* bones being selected [T37247]
|
||||||
|
*/
|
||||||
|
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tag armature for copy-on-write update (since act_bone is in armature not object). */
|
||||||
|
DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tag armature for copy-on-write update (since act_bone is in armature not object). */
|
changed = true;
|
||||||
DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changed || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
|
bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
|
||||||
@@ -226,9 +242,7 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
|
|||||||
Base *base,
|
Base *base,
|
||||||
const struct GPUSelectResult *buffer,
|
const struct GPUSelectResult *buffer,
|
||||||
const short hits,
|
const short hits,
|
||||||
bool extend,
|
const struct SelectPick_Params *params,
|
||||||
bool deselect,
|
|
||||||
bool toggle,
|
|
||||||
bool do_nearest)
|
bool do_nearest)
|
||||||
{
|
{
|
||||||
Object *ob = base->object;
|
Object *ob = base->object;
|
||||||
@@ -243,9 +257,7 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
|
|||||||
nearBone = ED_armature_pick_bone_from_selectbuffer(
|
nearBone = ED_armature_pick_bone_from_selectbuffer(
|
||||||
&base, 1, buffer, hits, 1, do_nearest, &base_dummy);
|
&base, 1, buffer, hits, 1, do_nearest, &base_dummy);
|
||||||
|
|
||||||
ED_armature_pose_select_pick_bone(view_layer, v3d, ob, nearBone, extend, deselect, toggle);
|
return ED_armature_pose_select_pick_bone(view_layer, v3d, ob, nearBone, params);
|
||||||
|
|
||||||
return nearBone != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_armature_pose_select_in_wpaint_mode(ViewLayer *view_layer, Base *base_select)
|
void ED_armature_pose_select_in_wpaint_mode(ViewLayer *view_layer, Base *base_select)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "ED_object.h"
|
#include "ED_object.h"
|
||||||
#include "ED_outliner.h"
|
#include "ED_outliner.h"
|
||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
|
#include "ED_select_utils.h"
|
||||||
#include "ED_transform.h"
|
#include "ED_transform.h"
|
||||||
#include "ED_transform_snap_object_context.h"
|
#include "ED_transform_snap_object_context.h"
|
||||||
#include "ED_types.h"
|
#include "ED_types.h"
|
||||||
@@ -4722,8 +4723,9 @@ void CURVE_OT_make_segment(wmOperatorType *ot)
|
|||||||
/** \name Pick Select from 3D View
|
/** \name Pick Select from 3D View
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
bool ED_curve_editnurb_select_pick(
|
bool ED_curve_editnurb_select_pick(bContext *C,
|
||||||
bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params)
|
||||||
{
|
{
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
ViewContext vc;
|
ViewContext vc;
|
||||||
@@ -4732,129 +4734,144 @@ bool ED_curve_editnurb_select_pick(
|
|||||||
BPoint *bp = NULL;
|
BPoint *bp = NULL;
|
||||||
Base *basact = NULL;
|
Base *basact = NULL;
|
||||||
short hand;
|
short hand;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
view3d_operator_needs_opengl(C);
|
view3d_operator_needs_opengl(C);
|
||||||
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
||||||
copy_v2_v2_int(vc.mval, mval);
|
copy_v2_v2_int(vc.mval, mval);
|
||||||
|
|
||||||
if (ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact)) {
|
const bool found = ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact);
|
||||||
|
|
||||||
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
|
/* Deselect everything. */
|
||||||
|
uint objects_len = 0;
|
||||||
|
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_iter = objects[ob_index];
|
||||||
|
|
||||||
|
ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb);
|
||||||
|
|
||||||
|
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
|
||||||
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
|
||||||
|
}
|
||||||
|
MEM_freeN(objects);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
Object *obedit = basact->object;
|
Object *obedit = basact->object;
|
||||||
Curve *cu = obedit->data;
|
Curve *cu = obedit->data;
|
||||||
ListBase *editnurb = object_editcurve_get(obedit);
|
ListBase *editnurb = object_editcurve_get(obedit);
|
||||||
const void *vert = BKE_curve_vert_active_get(cu);
|
const void *vert = BKE_curve_vert_active_get(cu);
|
||||||
|
|
||||||
if (!extend && !deselect && !toggle) {
|
switch (params->sel_op) {
|
||||||
uint objects_len = 0;
|
case SEL_OP_ADD: {
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
|
if (bezt) {
|
||||||
vc.view_layer, vc.v3d, &objects_len);
|
if (hand == 1) {
|
||||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
select_beztriple(bezt, SELECT, SELECT, HIDDEN);
|
||||||
Object *ob_iter = objects[ob_index];
|
|
||||||
|
|
||||||
ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb);
|
|
||||||
|
|
||||||
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
|
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
|
|
||||||
}
|
|
||||||
MEM_freeN(objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extend) {
|
|
||||||
if (bezt) {
|
|
||||||
if (hand == 1) {
|
|
||||||
select_beztriple(bezt, SELECT, SELECT, HIDDEN);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (hand == 0) {
|
|
||||||
bezt->f1 |= SELECT;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bezt->f3 |= SELECT;
|
if (hand == 0) {
|
||||||
}
|
bezt->f1 |= SELECT;
|
||||||
}
|
}
|
||||||
BKE_curve_nurb_vert_active_set(cu, nu, bezt);
|
else {
|
||||||
}
|
bezt->f3 |= SELECT;
|
||||||
else {
|
|
||||||
select_bpoint(bp, SELECT, SELECT, HIDDEN);
|
|
||||||
BKE_curve_nurb_vert_active_set(cu, nu, bp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (deselect) {
|
|
||||||
if (bezt) {
|
|
||||||
if (hand == 1) {
|
|
||||||
select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
|
|
||||||
if (bezt == vert) {
|
|
||||||
cu->actvert = CU_ACT_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (hand == 0) {
|
|
||||||
bezt->f1 &= ~SELECT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bezt->f3 &= ~SELECT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
select_bpoint(bp, DESELECT, SELECT, HIDDEN);
|
|
||||||
if (bp == vert) {
|
|
||||||
cu->actvert = CU_ACT_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (toggle) {
|
|
||||||
if (bezt) {
|
|
||||||
if (hand == 1) {
|
|
||||||
if (bezt->f2 & SELECT) {
|
|
||||||
select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
|
|
||||||
if (bezt == vert) {
|
|
||||||
cu->actvert = CU_ACT_NONE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
BKE_curve_nurb_vert_active_set(cu, nu, bezt);
|
||||||
select_beztriple(bezt, SELECT, SELECT, HIDDEN);
|
|
||||||
BKE_curve_nurb_vert_active_set(cu, nu, bezt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (hand == 0) {
|
|
||||||
bezt->f1 ^= SELECT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bezt->f3 ^= SELECT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (bp->f1 & SELECT) {
|
|
||||||
select_bpoint(bp, DESELECT, SELECT, HIDDEN);
|
|
||||||
if (bp == vert) {
|
|
||||||
cu->actvert = CU_ACT_NONE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
select_bpoint(bp, SELECT, SELECT, HIDDEN);
|
select_bpoint(bp, SELECT, SELECT, HIDDEN);
|
||||||
BKE_curve_nurb_vert_active_set(cu, nu, bp);
|
BKE_curve_nurb_vert_active_set(cu, nu, bp);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case SEL_OP_SUB: {
|
||||||
else {
|
if (bezt) {
|
||||||
BKE_nurbList_flag_set(editnurb, SELECT, false);
|
if (hand == 1) {
|
||||||
|
select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
|
||||||
if (bezt) {
|
if (bezt == vert) {
|
||||||
|
cu->actvert = CU_ACT_NONE;
|
||||||
if (hand == 1) {
|
}
|
||||||
select_beztriple(bezt, SELECT, SELECT, HIDDEN);
|
}
|
||||||
}
|
else if (hand == 0) {
|
||||||
else {
|
bezt->f1 &= ~SELECT;
|
||||||
if (hand == 0) {
|
|
||||||
bezt->f1 |= SELECT;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bezt->f3 |= SELECT;
|
bezt->f3 &= ~SELECT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BKE_curve_nurb_vert_active_set(cu, nu, bezt);
|
else {
|
||||||
|
select_bpoint(bp, DESELECT, SELECT, HIDDEN);
|
||||||
|
if (bp == vert) {
|
||||||
|
cu->actvert = CU_ACT_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else {
|
case SEL_OP_XOR: {
|
||||||
select_bpoint(bp, SELECT, SELECT, HIDDEN);
|
if (bezt) {
|
||||||
BKE_curve_nurb_vert_active_set(cu, nu, bp);
|
if (hand == 1) {
|
||||||
|
if (bezt->f2 & SELECT) {
|
||||||
|
select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
|
||||||
|
if (bezt == vert) {
|
||||||
|
cu->actvert = CU_ACT_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
select_beztriple(bezt, SELECT, SELECT, HIDDEN);
|
||||||
|
BKE_curve_nurb_vert_active_set(cu, nu, bezt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (hand == 0) {
|
||||||
|
bezt->f1 ^= SELECT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bezt->f3 ^= SELECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (bp->f1 & SELECT) {
|
||||||
|
select_bpoint(bp, DESELECT, SELECT, HIDDEN);
|
||||||
|
if (bp == vert) {
|
||||||
|
cu->actvert = CU_ACT_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
select_bpoint(bp, SELECT, SELECT, HIDDEN);
|
||||||
|
BKE_curve_nurb_vert_active_set(cu, nu, bp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
BKE_nurbList_flag_set(editnurb, SELECT, false);
|
||||||
|
|
||||||
|
if (bezt) {
|
||||||
|
|
||||||
|
if (hand == 1) {
|
||||||
|
select_beztriple(bezt, SELECT, SELECT, HIDDEN);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (hand == 0) {
|
||||||
|
bezt->f1 |= SELECT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bezt->f3 |= SELECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BKE_curve_nurb_vert_active_set(cu, nu, bezt);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
select_bpoint(bp, SELECT, SELECT, HIDDEN);
|
||||||
|
BKE_curve_nurb_vert_active_set(cu, nu, bp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4876,10 +4893,10 @@ bool ED_curve_editnurb_select_pick(
|
|||||||
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
|
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||||
|
|
||||||
return true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return changed || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|||||||
@@ -2184,7 +2184,10 @@ void FONT_OT_unlink(wmOperatorType *ot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ED_curve_editfont_select_pick(
|
bool ED_curve_editfont_select_pick(
|
||||||
bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
|
bContext *C,
|
||||||
|
const int mval[2],
|
||||||
|
/* NOTE: `params->deselect_all` is ignored as only one text-box is active at once. */
|
||||||
|
const struct SelectPick_Params *params)
|
||||||
{
|
{
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
Object *obedit = CTX_data_edit_object(C);
|
Object *obedit = CTX_data_edit_object(C);
|
||||||
@@ -2203,9 +2206,7 @@ bool ED_curve_editfont_select_pick(
|
|||||||
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
|
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
|
||||||
|
|
||||||
/* currently only select active */
|
/* currently only select active */
|
||||||
(void)extend;
|
(void)params;
|
||||||
(void)deselect;
|
|
||||||
(void)toggle;
|
|
||||||
|
|
||||||
for (i_iter = 0; i_iter < cu->totbox; i_iter++) {
|
for (i_iter = 0; i_iter < cu->totbox; i_iter++) {
|
||||||
int i = (i_iter + i_actbox) % cu->totbox;
|
int i = (i_iter + i_actbox) % cu->totbox;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ struct MeshDeformModifierData;
|
|||||||
struct Object;
|
struct Object;
|
||||||
struct ReportList;
|
struct ReportList;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
|
struct SelectPick_Params;
|
||||||
struct UndoType;
|
struct UndoType;
|
||||||
struct View3D;
|
struct View3D;
|
||||||
struct ViewLayer;
|
struct ViewLayer;
|
||||||
@@ -164,18 +165,20 @@ bool ED_armature_edit_deselect_all_visible(struct Object *obedit);
|
|||||||
bool ED_armature_edit_deselect_all_multi_ex(struct Base **bases, uint bases_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_ex(struct Base **bases, uint bases_len);
|
||||||
bool ED_armature_edit_deselect_all_visible_multi(struct bContext *C);
|
bool ED_armature_edit_deselect_all_visible_multi(struct bContext *C);
|
||||||
|
/**
|
||||||
|
* \return True when pick finds an element or the selection changed.
|
||||||
|
*/
|
||||||
bool ED_armature_edit_select_pick_bone(struct bContext *C,
|
bool ED_armature_edit_select_pick_bone(struct bContext *C,
|
||||||
struct Base *basact,
|
struct Base *basact,
|
||||||
struct EditBone *ebone,
|
struct EditBone *ebone,
|
||||||
int selmask,
|
int selmask,
|
||||||
bool extend,
|
const struct SelectPick_Params *params);
|
||||||
bool deselect,
|
|
||||||
bool toggle);
|
|
||||||
/**
|
/**
|
||||||
* Bone selection picking for armature edit-mode in the view3d.
|
* Bone selection picking for armature edit-mode in the view3d.
|
||||||
*/
|
*/
|
||||||
bool ED_armature_edit_select_pick(
|
bool ED_armature_edit_select_pick(struct bContext *C,
|
||||||
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params);
|
||||||
/**
|
/**
|
||||||
* Perform a selection operation on elements which have been 'touched',
|
* Perform a selection operation on elements which have been 'touched',
|
||||||
* use for lasso & border select but can be used elsewhere too.
|
* use for lasso & border select but can be used elsewhere too.
|
||||||
@@ -305,25 +308,26 @@ void ED_pose_recalculate_paths(struct bContext *C,
|
|||||||
|
|
||||||
/* pose_select.c */
|
/* pose_select.c */
|
||||||
|
|
||||||
void ED_armature_pose_select_pick_bone(struct ViewLayer *view_layer,
|
/**
|
||||||
|
* \return True when pick finds an element or the selection changed.
|
||||||
|
*/
|
||||||
|
bool ED_armature_pose_select_pick_bone(struct ViewLayer *view_layer,
|
||||||
struct View3D *v3d,
|
struct View3D *v3d,
|
||||||
struct Object *ob,
|
struct Object *ob,
|
||||||
struct Bone *bone,
|
struct Bone *bone,
|
||||||
bool extend,
|
const struct SelectPick_Params *params);
|
||||||
bool deselect,
|
|
||||||
bool toggle);
|
|
||||||
/**
|
/**
|
||||||
* Called for mode-less pose selection.
|
* Called for mode-less pose selection.
|
||||||
* assumes the active object is still on old situation.
|
* assumes the active object is still on old situation.
|
||||||
|
*
|
||||||
|
* \return True when pick finds an element or the selection changed.
|
||||||
*/
|
*/
|
||||||
bool ED_armature_pose_select_pick_with_buffer(struct ViewLayer *view_layer,
|
bool ED_armature_pose_select_pick_with_buffer(struct ViewLayer *view_layer,
|
||||||
struct View3D *v3d,
|
struct View3D *v3d,
|
||||||
struct Base *base,
|
struct Base *base,
|
||||||
const struct GPUSelectResult *buffer,
|
const struct GPUSelectResult *buffer,
|
||||||
short hits,
|
short hits,
|
||||||
bool extend,
|
const struct SelectPick_Params *params,
|
||||||
bool deselect,
|
|
||||||
bool toggle,
|
|
||||||
bool do_nearest);
|
bool do_nearest);
|
||||||
/**
|
/**
|
||||||
* While in weight-paint mode, a single pose may be active as well.
|
* While in weight-paint mode, a single pose may be active as well.
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ struct EditNurb;
|
|||||||
struct Main;
|
struct Main;
|
||||||
struct Nurb;
|
struct Nurb;
|
||||||
struct Object;
|
struct Object;
|
||||||
|
struct SelectPick_Params;
|
||||||
struct Text;
|
struct Text;
|
||||||
struct UndoType;
|
struct UndoType;
|
||||||
struct View3D;
|
struct View3D;
|
||||||
@@ -46,8 +47,12 @@ void ED_curve_editnurb_load(struct Main *bmain, struct Object *obedit);
|
|||||||
void ED_curve_editnurb_make(struct Object *obedit);
|
void ED_curve_editnurb_make(struct Object *obedit);
|
||||||
void ED_curve_editnurb_free(struct Object *obedit);
|
void ED_curve_editnurb_free(struct Object *obedit);
|
||||||
|
|
||||||
bool ED_curve_editnurb_select_pick(
|
/**
|
||||||
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
|
* \return True when pick finds an element or the selection changed.
|
||||||
|
*/
|
||||||
|
bool ED_curve_editnurb_select_pick(struct bContext *C,
|
||||||
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params);
|
||||||
|
|
||||||
struct Nurb *ED_curve_add_nurbs_primitive(
|
struct Nurb *ED_curve_add_nurbs_primitive(
|
||||||
struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newob);
|
struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newob);
|
||||||
@@ -100,10 +105,13 @@ int ED_curve_updateAnimPaths(struct Main *bmain, struct Curve *cu);
|
|||||||
bool ED_curve_active_center(struct Curve *cu, float center[3]);
|
bool ED_curve_active_center(struct Curve *cu, float center[3]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TextBox selection
|
* Text box selection.
|
||||||
|
*
|
||||||
|
* \return True when pick finds an element or the selection changed.
|
||||||
*/
|
*/
|
||||||
bool ED_curve_editfont_select_pick(
|
bool ED_curve_editfont_select_pick(struct bContext *C,
|
||||||
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params);
|
||||||
|
|
||||||
/* editfont_undo.c */
|
/* editfont_undo.c */
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ extern "C" {
|
|||||||
|
|
||||||
struct Base;
|
struct Base;
|
||||||
struct Object;
|
struct Object;
|
||||||
|
struct SelectPick_Params;
|
||||||
struct UndoType;
|
struct UndoType;
|
||||||
struct wmKeyConfig;
|
struct wmKeyConfig;
|
||||||
|
|
||||||
@@ -24,8 +25,12 @@ void ED_keymap_lattice(struct wmKeyConfig *keyconf);
|
|||||||
/* editlattice_select.c */
|
/* editlattice_select.c */
|
||||||
|
|
||||||
bool 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);
|
* \return True when pick finds an element or the selection changed.
|
||||||
|
*/
|
||||||
|
bool ED_lattice_select_pick(struct bContext *C,
|
||||||
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params);
|
||||||
|
|
||||||
bool ED_lattice_deselect_all_multi_ex(struct Base **bases, uint bases_len);
|
bool ED_lattice_deselect_all_multi_ex(struct Base **bases, uint bases_len);
|
||||||
bool ED_lattice_deselect_all_multi(struct bContext *C);
|
bool ED_lattice_deselect_all_multi(struct bContext *C);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ extern "C" {
|
|||||||
|
|
||||||
struct Base;
|
struct Base;
|
||||||
struct Object;
|
struct Object;
|
||||||
|
struct SelectPick_Params;
|
||||||
struct UndoType;
|
struct UndoType;
|
||||||
struct bContext;
|
struct bContext;
|
||||||
struct wmKeyConfig;
|
struct wmKeyConfig;
|
||||||
@@ -32,10 +33,13 @@ struct MetaElem *ED_mball_add_primitive(struct bContext *C,
|
|||||||
int type);
|
int type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select MetaElement with mouse click (user can select radius circle or stiffness circle).
|
* Select meta-element with mouse click (user can select radius circle or stiffness circle).
|
||||||
|
*
|
||||||
|
* \return True when pick finds an element or the selection changed.
|
||||||
*/
|
*/
|
||||||
bool ED_mball_select_pick(
|
bool ED_mball_select_pick(struct bContext *C,
|
||||||
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params);
|
||||||
|
|
||||||
bool ED_mball_deselect_all_multi_ex(struct Base **bases, uint bases_len);
|
bool ED_mball_deselect_all_multi_ex(struct Base **bases, uint bases_len);
|
||||||
bool ED_mball_deselect_all_multi(struct bContext *C);
|
bool ED_mball_deselect_all_multi(struct bContext *C);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ struct Mesh;
|
|||||||
struct Object;
|
struct Object;
|
||||||
struct ReportList;
|
struct ReportList;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
|
struct SelectPick_Params;
|
||||||
struct UndoType;
|
struct UndoType;
|
||||||
struct UvMapVert;
|
struct UvMapVert;
|
||||||
struct UvVertMap;
|
struct UvVertMap;
|
||||||
@@ -268,8 +269,9 @@ bool EDBM_unified_findnearest_from_raycast(struct ViewContext *vc,
|
|||||||
struct BMEdge **r_eed,
|
struct BMEdge **r_eed,
|
||||||
struct BMFace **r_efa);
|
struct BMFace **r_efa);
|
||||||
|
|
||||||
bool EDBM_select_pick(
|
bool EDBM_select_pick(struct bContext *C,
|
||||||
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When switching select mode, makes sure selection is consistent for editing
|
* When switching select mode, makes sure selection is consistent for editing
|
||||||
@@ -387,12 +389,13 @@ void ED_keymap_mesh(struct wmKeyConfig *keyconf);
|
|||||||
* use in object mode when selecting faces (while painting).
|
* use in object mode when selecting faces (while painting).
|
||||||
*/
|
*/
|
||||||
void paintface_flush_flags(struct bContext *C, struct Object *ob, short flag);
|
void paintface_flush_flags(struct bContext *C, struct Object *ob, short flag);
|
||||||
|
/**
|
||||||
|
* \return True when pick finds an element or the selection changed.
|
||||||
|
*/
|
||||||
bool paintface_mouse_select(struct bContext *C,
|
bool paintface_mouse_select(struct bContext *C,
|
||||||
struct Object *ob,
|
|
||||||
const int mval[2],
|
const int mval[2],
|
||||||
bool extend,
|
const struct SelectPick_Params *params,
|
||||||
bool deselect,
|
struct Object *ob);
|
||||||
bool toggle);
|
|
||||||
bool paintface_deselect_all_visible(struct bContext *C,
|
bool paintface_deselect_all_visible(struct bContext *C,
|
||||||
struct Object *ob,
|
struct Object *ob,
|
||||||
int action,
|
int action,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ struct PTCacheEdit;
|
|||||||
struct ParticleEditSettings;
|
struct ParticleEditSettings;
|
||||||
struct ParticleSystem;
|
struct ParticleSystem;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
|
struct SelectPick_Params;
|
||||||
struct UndoType;
|
struct UndoType;
|
||||||
struct ViewLayer;
|
struct ViewLayer;
|
||||||
struct bContext;
|
struct bContext;
|
||||||
@@ -54,8 +55,9 @@ void PE_update_object(struct Depsgraph *depsgraph,
|
|||||||
|
|
||||||
/* selection tools */
|
/* selection tools */
|
||||||
|
|
||||||
bool PE_mouse_particles(
|
bool PE_mouse_particles(struct bContext *C,
|
||||||
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params);
|
||||||
bool PE_box_select(struct bContext *C, const struct rcti *rect, int sel_op);
|
bool PE_box_select(struct bContext *C, const struct rcti *rect, int sel_op);
|
||||||
bool PE_circle_select(struct bContext *C,
|
bool PE_circle_select(struct bContext *C,
|
||||||
struct wmGenericUserData *wm_userdata,
|
struct wmGenericUserData *wm_userdata,
|
||||||
|
|||||||
@@ -70,6 +70,25 @@ bool ED_select_similar_compare_float_tree(const struct KDTree_1d *tree,
|
|||||||
*/
|
*/
|
||||||
eSelectOp ED_select_op_modal(eSelectOp sel_op, bool is_first);
|
eSelectOp ED_select_op_modal(eSelectOp sel_op, bool is_first);
|
||||||
|
|
||||||
|
/** Argument passed to picking functions. */
|
||||||
|
struct SelectPick_Params {
|
||||||
|
/**
|
||||||
|
* - #SEL_OP_ADD named "extend" from operators.
|
||||||
|
* - #SEL_OP_SUB named "deselect" from operators.
|
||||||
|
* - #SEL_OP_XOR named "toggle" from operators.
|
||||||
|
* - #SEL_OP_AND (never used for picking).
|
||||||
|
* - #SEL_OP_SET use when "extend", "deselect" and "toggle" are all disabled.
|
||||||
|
*/
|
||||||
|
eSelectOp sel_op;
|
||||||
|
/** Deselect all, even when there is nothing found at the cursor location. */
|
||||||
|
bool deselect_all;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility to get #eSelectPickMode from booleans for convenience.
|
||||||
|
*/
|
||||||
|
eSelectOp ED_select_op_from_booleans(bool extend, bool deselect, bool toggle);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -616,49 +616,63 @@ static BPoint *findnearestLattvert(ViewContext *vc, int sel, Base **r_base)
|
|||||||
return data.bp;
|
return data.bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ED_lattice_select_pick(
|
bool ED_lattice_select_pick(bContext *C, const int mval[2], const struct SelectPick_Params *params)
|
||||||
bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
|
|
||||||
{
|
{
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
ViewContext vc;
|
ViewContext vc;
|
||||||
BPoint *bp = NULL;
|
BPoint *bp = NULL;
|
||||||
Base *basact = NULL;
|
Base *basact = NULL;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
||||||
vc.mval[0] = mval[0];
|
vc.mval[0] = mval[0];
|
||||||
vc.mval[1] = mval[1];
|
vc.mval[1] = mval[1];
|
||||||
|
|
||||||
bp = findnearestLattvert(&vc, true, &basact);
|
bp = findnearestLattvert(&vc, true, &basact);
|
||||||
if (bp) {
|
const bool found = (bp != NULL);
|
||||||
|
|
||||||
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
|
/* Deselect everything. */
|
||||||
|
uint objects_len = 0;
|
||||||
|
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];
|
||||||
|
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);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
||||||
Lattice *lt = ((Lattice *)vc.obedit->data)->editlatt->latt;
|
Lattice *lt = ((Lattice *)vc.obedit->data)->editlatt->latt;
|
||||||
|
|
||||||
if (!extend && !deselect && !toggle) {
|
switch (params->sel_op) {
|
||||||
uint objects_len = 0;
|
case SEL_OP_ADD: {
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
|
bp->f1 |= SELECT;
|
||||||
vc.view_layer, vc.v3d, &objects_len);
|
break;
|
||||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
}
|
||||||
Object *ob = objects[ob_index];
|
case SEL_OP_SUB: {
|
||||||
if (ED_lattice_flags_set(ob, 0)) {
|
bp->f1 &= ~SELECT;
|
||||||
DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
|
break;
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
|
}
|
||||||
}
|
case SEL_OP_XOR: {
|
||||||
|
bp->f1 ^= SELECT; /* swap */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
ED_lattice_flags_set(vc.obedit, 0);
|
||||||
|
bp->f1 |= SELECT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
MEM_freeN(objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extend) {
|
|
||||||
bp->f1 |= SELECT;
|
|
||||||
}
|
|
||||||
else if (deselect) {
|
|
||||||
bp->f1 &= ~SELECT;
|
|
||||||
}
|
|
||||||
else if (toggle) {
|
|
||||||
bp->f1 ^= SELECT; /* swap */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ED_lattice_flags_set(vc.obedit, 0);
|
|
||||||
bp->f1 |= SELECT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bp->f1 & SELECT) {
|
if (bp->f1 & SELECT) {
|
||||||
@@ -675,10 +689,10 @@ bool ED_lattice_select_pick(
|
|||||||
DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
|
DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||||
|
|
||||||
return true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return changed || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|||||||
@@ -366,59 +366,71 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool paintface_mouse_select(
|
bool paintface_mouse_select(struct bContext *C,
|
||||||
struct bContext *C, Object *ob, const int mval[2], bool extend, bool deselect, bool toggle)
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params,
|
||||||
|
Object *ob)
|
||||||
{
|
{
|
||||||
Mesh *me;
|
Mesh *me;
|
||||||
MPoly *mpoly_sel;
|
MPoly *mpoly_sel = NULL;
|
||||||
uint index;
|
uint index;
|
||||||
|
bool changed = false;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
/* Get the face under the cursor */
|
/* Get the face under the cursor */
|
||||||
me = BKE_mesh_from_object(ob);
|
me = BKE_mesh_from_object(ob);
|
||||||
|
|
||||||
if (!ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
|
if (ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
|
||||||
return false;
|
if (index < me->totpoly) {
|
||||||
}
|
mpoly_sel = me->mpoly + index;
|
||||||
|
if ((mpoly_sel->flag & ME_HIDE) == 0) {
|
||||||
if (index >= me->totpoly) {
|
found = true;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
mpoly_sel = me->mpoly + index;
|
|
||||||
if (mpoly_sel->flag & ME_HIDE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear flags */
|
|
||||||
if (!extend && !deselect && !toggle) {
|
|
||||||
paintface_deselect_all_visible(C, ob, SEL_DESELECT, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
me->act_face = (int)index;
|
|
||||||
|
|
||||||
if (extend) {
|
|
||||||
mpoly_sel->flag |= ME_FACE_SEL;
|
|
||||||
}
|
|
||||||
else if (deselect) {
|
|
||||||
mpoly_sel->flag &= ~ME_FACE_SEL;
|
|
||||||
}
|
|
||||||
else if (toggle) {
|
|
||||||
if (mpoly_sel->flag & ME_FACE_SEL) {
|
|
||||||
mpoly_sel->flag &= ~ME_FACE_SEL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mpoly_sel->flag |= ME_FACE_SEL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
mpoly_sel->flag |= ME_FACE_SEL;
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
|
changed |= paintface_deselect_all_visible(C, ob, SEL_DESELECT, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* image window redraw */
|
if (found) {
|
||||||
|
me->act_face = (int)index;
|
||||||
|
|
||||||
paintface_flush_flags(C, ob, SELECT);
|
switch (params->sel_op) {
|
||||||
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
|
case SEL_OP_ADD: {
|
||||||
return true;
|
mpoly_sel->flag |= ME_FACE_SEL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SUB: {
|
||||||
|
mpoly_sel->flag &= ~ME_FACE_SEL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
if (mpoly_sel->flag & ME_FACE_SEL) {
|
||||||
|
mpoly_sel->flag &= ~ME_FACE_SEL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mpoly_sel->flag |= ME_FACE_SEL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
mpoly_sel->flag |= ME_FACE_SEL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* image window redraw */
|
||||||
|
|
||||||
|
paintface_flush_flags(C, ob, SELECT);
|
||||||
|
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
return changed || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void paintvert_flush_flags(Object *ob)
|
void paintvert_flush_flags(Object *ob)
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "ED_mesh.h"
|
#include "ED_mesh.h"
|
||||||
#include "ED_object.h"
|
#include "ED_object.h"
|
||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
|
#include "ED_select_utils.h"
|
||||||
#include "ED_uvedit.h"
|
#include "ED_uvedit.h"
|
||||||
#include "ED_view3d.h"
|
#include "ED_view3d.h"
|
||||||
|
|
||||||
@@ -700,7 +701,10 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
|
|||||||
/* TODO(dfelinto): right now we try to find the closest element twice.
|
/* TODO(dfelinto): right now we try to find the closest element twice.
|
||||||
* The ideal is to refactor EDBM_select_pick so it doesn't
|
* The ideal is to refactor EDBM_select_pick so it doesn't
|
||||||
* have to pick the nearest vert/edge/face again. */
|
* have to pick the nearest vert/edge/face again. */
|
||||||
EDBM_select_pick(C, event->mval, true, false, false);
|
const struct SelectPick_Params params = {
|
||||||
|
.sel_op = SEL_OP_ADD,
|
||||||
|
};
|
||||||
|
EDBM_select_pick(C, event->mval, ¶ms);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2016,7 +2016,7 @@ void MESH_OT_select_interior_faces(wmOperatorType *ot)
|
|||||||
* Gets called via generic mouse select operator.
|
* Gets called via generic mouse select operator.
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
|
bool EDBM_select_pick(bContext *C, const int mval[2], const struct SelectPick_Params *params)
|
||||||
{
|
{
|
||||||
ViewContext vc;
|
ViewContext vc;
|
||||||
|
|
||||||
@@ -2033,100 +2033,148 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect
|
|||||||
uint bases_len = 0;
|
uint bases_len = 0;
|
||||||
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
|
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
|
||||||
|
|
||||||
bool ok = false;
|
bool changed = false;
|
||||||
|
const bool found = unified_findnearest(
|
||||||
|
&vc, bases, bases_len, &base_index_active, &eve, &eed, &efa);
|
||||||
|
|
||||||
if (unified_findnearest(&vc, bases, bases_len, &base_index_active, &eve, &eed, &efa)) {
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
|
/* Deselect everything. */
|
||||||
|
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
||||||
|
Base *base_iter = bases[base_index];
|
||||||
|
Object *ob_iter = base_iter->object;
|
||||||
|
EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT);
|
||||||
|
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
|
||||||
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
Base *basact = bases[base_index_active];
|
Base *basact = bases[base_index_active];
|
||||||
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
||||||
|
|
||||||
/* Deselect everything */
|
|
||||||
if (extend == false && deselect == false && toggle == false) {
|
|
||||||
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
|
||||||
Base *base_iter = bases[base_index];
|
|
||||||
Object *ob_iter = base_iter->object;
|
|
||||||
EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT);
|
|
||||||
if (basact->object != ob_iter) {
|
|
||||||
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
|
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (efa) {
|
if (efa) {
|
||||||
if (extend) {
|
switch (params->sel_op) {
|
||||||
/* set the last selected face */
|
case SEL_OP_ADD: {
|
||||||
BM_mesh_active_face_set(vc.em->bm, efa);
|
BM_mesh_active_face_set(vc.em->bm, efa);
|
||||||
|
|
||||||
/* Work-around: deselect first, so we can guarantee it will */
|
/* Work-around: deselect first, so we can guarantee it will
|
||||||
/* be active even if it was already selected */
|
* be active even if it was already selected. */
|
||||||
BM_select_history_remove(vc.em->bm, efa);
|
|
||||||
BM_face_select_set(vc.em->bm, efa, false);
|
|
||||||
BM_select_history_store(vc.em->bm, efa);
|
|
||||||
BM_face_select_set(vc.em->bm, efa, true);
|
|
||||||
}
|
|
||||||
else if (deselect) {
|
|
||||||
BM_select_history_remove(vc.em->bm, efa);
|
|
||||||
BM_face_select_set(vc.em->bm, efa, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* set the last selected face */
|
|
||||||
BM_mesh_active_face_set(vc.em->bm, efa);
|
|
||||||
|
|
||||||
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
|
||||||
BM_select_history_store(vc.em->bm, efa);
|
|
||||||
BM_face_select_set(vc.em->bm, efa, true);
|
|
||||||
}
|
|
||||||
else if (toggle) {
|
|
||||||
BM_select_history_remove(vc.em->bm, efa);
|
BM_select_history_remove(vc.em->bm, efa);
|
||||||
BM_face_select_set(vc.em->bm, efa, false);
|
BM_face_select_set(vc.em->bm, efa, false);
|
||||||
|
BM_select_history_store(vc.em->bm, efa);
|
||||||
|
BM_face_select_set(vc.em->bm, efa, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SUB: {
|
||||||
|
BM_select_history_remove(vc.em->bm, efa);
|
||||||
|
BM_face_select_set(vc.em->bm, efa, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
BM_mesh_active_face_set(vc.em->bm, efa);
|
||||||
|
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||||
|
BM_select_history_store(vc.em->bm, efa);
|
||||||
|
BM_face_select_set(vc.em->bm, efa, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BM_select_history_remove(vc.em->bm, efa);
|
||||||
|
BM_face_select_set(vc.em->bm, efa, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
BM_mesh_active_face_set(vc.em->bm, efa);
|
||||||
|
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||||
|
BM_select_history_store(vc.em->bm, efa);
|
||||||
|
BM_face_select_set(vc.em->bm, efa, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (eed) {
|
else if (eed) {
|
||||||
if (extend) {
|
|
||||||
/* Work-around: deselect first, so we can guarantee it will */
|
switch (params->sel_op) {
|
||||||
/* be active even if it was already selected */
|
case SEL_OP_ADD: {
|
||||||
BM_select_history_remove(vc.em->bm, eed);
|
/* Work-around: deselect first, so we can guarantee it will
|
||||||
BM_edge_select_set(vc.em->bm, eed, false);
|
* be active even if it was already selected. */
|
||||||
BM_select_history_store(vc.em->bm, eed);
|
|
||||||
BM_edge_select_set(vc.em->bm, eed, true);
|
|
||||||
}
|
|
||||||
else if (deselect) {
|
|
||||||
BM_select_history_remove(vc.em->bm, eed);
|
|
||||||
BM_edge_select_set(vc.em->bm, eed, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
|
|
||||||
BM_select_history_store(vc.em->bm, eed);
|
|
||||||
BM_edge_select_set(vc.em->bm, eed, true);
|
|
||||||
}
|
|
||||||
else if (toggle) {
|
|
||||||
BM_select_history_remove(vc.em->bm, eed);
|
BM_select_history_remove(vc.em->bm, eed);
|
||||||
BM_edge_select_set(vc.em->bm, eed, false);
|
BM_edge_select_set(vc.em->bm, eed, false);
|
||||||
|
BM_select_history_store(vc.em->bm, eed);
|
||||||
|
BM_edge_select_set(vc.em->bm, eed, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SUB: {
|
||||||
|
BM_select_history_remove(vc.em->bm, eed);
|
||||||
|
BM_edge_select_set(vc.em->bm, eed, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
if (!BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
|
||||||
|
BM_select_history_store(vc.em->bm, eed);
|
||||||
|
BM_edge_select_set(vc.em->bm, eed, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BM_select_history_remove(vc.em->bm, eed);
|
||||||
|
BM_edge_select_set(vc.em->bm, eed, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
if (!BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
|
||||||
|
BM_select_history_store(vc.em->bm, eve);
|
||||||
|
BM_vert_select_set(vc.em->bm, eve, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (eve) {
|
else if (eve) {
|
||||||
if (extend) {
|
switch (params->sel_op) {
|
||||||
/* Work-around: deselect first, so we can guarantee it will */
|
case SEL_OP_ADD: {
|
||||||
/* be active even if it was already selected */
|
/* Work-around: deselect first, so we can guarantee it will
|
||||||
BM_select_history_remove(vc.em->bm, eve);
|
* be active even if it was already selected. */
|
||||||
BM_vert_select_set(vc.em->bm, eve, false);
|
|
||||||
BM_select_history_store(vc.em->bm, eve);
|
|
||||||
BM_vert_select_set(vc.em->bm, eve, true);
|
|
||||||
}
|
|
||||||
else if (deselect) {
|
|
||||||
BM_select_history_remove(vc.em->bm, eve);
|
|
||||||
BM_vert_select_set(vc.em->bm, eve, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
|
|
||||||
BM_select_history_store(vc.em->bm, eve);
|
|
||||||
BM_vert_select_set(vc.em->bm, eve, true);
|
|
||||||
}
|
|
||||||
else if (toggle) {
|
|
||||||
BM_select_history_remove(vc.em->bm, eve);
|
BM_select_history_remove(vc.em->bm, eve);
|
||||||
BM_vert_select_set(vc.em->bm, eve, false);
|
BM_vert_select_set(vc.em->bm, eve, false);
|
||||||
|
BM_select_history_store(vc.em->bm, eve);
|
||||||
|
BM_vert_select_set(vc.em->bm, eve, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SUB: {
|
||||||
|
BM_select_history_remove(vc.em->bm, eve);
|
||||||
|
BM_vert_select_set(vc.em->bm, eve, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
if (!BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
|
||||||
|
BM_select_history_store(vc.em->bm, eve);
|
||||||
|
BM_vert_select_set(vc.em->bm, eve, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BM_select_history_remove(vc.em->bm, eve);
|
||||||
|
BM_vert_select_set(vc.em->bm, eve, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
if (!BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
|
||||||
|
BM_select_history_store(vc.em->bm, eve);
|
||||||
|
BM_vert_select_set(vc.em->bm, eve, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2168,12 +2216,12 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect
|
|||||||
DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
|
DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||||
|
|
||||||
ok = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(bases);
|
MEM_freeN(bases);
|
||||||
|
|
||||||
return ok;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
#include "ED_object.h"
|
#include "ED_object.h"
|
||||||
#include "ED_outliner.h"
|
#include "ED_outliner.h"
|
||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
|
#include "ED_select_utils.h"
|
||||||
#include "ED_transform.h"
|
#include "ED_transform.h"
|
||||||
#include "ED_uvedit.h"
|
#include "ED_uvedit.h"
|
||||||
#include "ED_view3d.h"
|
#include "ED_view3d.h"
|
||||||
@@ -8540,7 +8541,10 @@ static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||||||
case EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED:
|
case EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED:
|
||||||
new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES;
|
new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES;
|
||||||
view3d_operator_needs_opengl(C);
|
view3d_operator_needs_opengl(C);
|
||||||
if (EDBM_select_pick(C, event->mval, false, false, false)) {
|
const struct SelectPick_Params params = {
|
||||||
|
.sel_op = SEL_OP_SET,
|
||||||
|
};
|
||||||
|
if (EDBM_select_pick(C, event->mval, ¶ms)) {
|
||||||
/* Point to newly selected active. */
|
/* Point to newly selected active. */
|
||||||
ED_object_calc_active_center_for_editmode(obedit, false, target);
|
ED_object_calc_active_center_for_editmode(obedit, false, target);
|
||||||
|
|
||||||
|
|||||||
@@ -736,7 +736,7 @@ void MBALL_OT_reveal_metaelems(wmOperatorType *ot)
|
|||||||
/** \name Select Pick Utility
|
/** \name Select Pick Utility
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
|
bool ED_mball_select_pick(bContext *C, const int mval[2], const struct SelectPick_Params *params)
|
||||||
{
|
{
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
static MetaElem *startelem = NULL;
|
static MetaElem *startelem = NULL;
|
||||||
@@ -744,6 +744,8 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
|
|||||||
int a, hits;
|
int a, hits;
|
||||||
GPUSelectResult buffer[MAXPICKELEMS];
|
GPUSelectResult buffer[MAXPICKELEMS];
|
||||||
rcti rect;
|
rcti rect;
|
||||||
|
bool changed = false;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
||||||
|
|
||||||
@@ -822,7 +824,9 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
|
|||||||
|
|
||||||
/* When some metaelem was found, then it is necessary to select or deselect it. */
|
/* When some metaelem was found, then it is necessary to select or deselect it. */
|
||||||
if (ml_act) {
|
if (ml_act) {
|
||||||
if (!extend && !deselect && !toggle) {
|
found = true;
|
||||||
|
|
||||||
|
if (params->sel_op == SEL_OP_SET) {
|
||||||
uint objects_len;
|
uint objects_len;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
|
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
|
||||||
vc.view_layer, vc.v3d, &objects_len);
|
vc.view_layer, vc.v3d, &objects_len);
|
||||||
@@ -840,26 +844,36 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
|
|||||||
MEM_freeN(objects);
|
MEM_freeN(objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extend) {
|
switch (params->sel_op) {
|
||||||
ml_act->flag |= SELECT;
|
case SEL_OP_ADD: {
|
||||||
}
|
|
||||||
else if (deselect) {
|
|
||||||
ml_act->flag &= ~SELECT;
|
|
||||||
}
|
|
||||||
else if (toggle) {
|
|
||||||
if (ml_act->flag & SELECT) {
|
|
||||||
ml_act->flag &= ~SELECT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ml_act->flag |= SELECT;
|
ml_act->flag |= SELECT;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case SEL_OP_SUB: {
|
||||||
else {
|
ml_act->flag &= ~SELECT;
|
||||||
/* Deselect all existing metaelems */
|
break;
|
||||||
BKE_mball_deselect_all(mb);
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
if (ml_act->flag & SELECT) {
|
||||||
|
ml_act->flag &= ~SELECT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ml_act->flag |= SELECT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
/* Deselect all existing metaelems */
|
||||||
|
BKE_mball_deselect_all(mb);
|
||||||
|
|
||||||
/* Select only metaelem clicked on */
|
/* Select only metaelem clicked on */
|
||||||
ml_act->flag |= SELECT;
|
ml_act->flag |= SELECT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mb->lastelem = ml_act;
|
mb->lastelem = ml_act;
|
||||||
@@ -871,13 +885,18 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
|
|||||||
ED_object_base_activate(C, base);
|
ED_object_base_activate(C, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FOREACH_BASE_IN_EDIT_MODE_END;
|
FOREACH_BASE_IN_EDIT_MODE_END;
|
||||||
|
|
||||||
return false;
|
if (params->deselect_all && !found) {
|
||||||
|
ED_mball_deselect_all_multi(C);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|||||||
@@ -487,6 +487,8 @@ typedef struct PEData {
|
|||||||
int select_action;
|
int select_action;
|
||||||
int select_toggle_action;
|
int select_toggle_action;
|
||||||
bool is_changed;
|
bool is_changed;
|
||||||
|
|
||||||
|
void *user_data;
|
||||||
} PEData;
|
} PEData;
|
||||||
|
|
||||||
static void PE_set_data(bContext *C, PEData *data)
|
static void PE_set_data(bContext *C, PEData *data)
|
||||||
@@ -1721,46 +1723,6 @@ static void select_keys(PEData *data,
|
|||||||
point->flag |= PEP_EDIT_RECALC;
|
point->flag |= PEP_EDIT_RECALC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extend_key_select(PEData *data, int point_index, int key_index, bool UNUSED(is_inside))
|
|
||||||
{
|
|
||||||
PTCacheEdit *edit = data->edit;
|
|
||||||
PTCacheEditPoint *point = edit->points + point_index;
|
|
||||||
PTCacheEditKey *key = point->keys + key_index;
|
|
||||||
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
PTCacheEdit *edit = data->edit;
|
|
||||||
PTCacheEditPoint *point = edit->points + point_index;
|
|
||||||
PTCacheEditKey *key = point->keys + key_index;
|
|
||||||
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
PTCacheEdit *edit = data->edit;
|
|
||||||
PTCacheEditPoint *point = edit->points + point_index;
|
|
||||||
PTCacheEditKey *key = point->keys + key_index;
|
|
||||||
|
|
||||||
key->flag ^= PEK_SELECT;
|
|
||||||
point->flag |= PEP_EDIT_RECALC;
|
|
||||||
data->is_changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@@ -1862,13 +1824,50 @@ void PARTICLE_OT_select_all(wmOperatorType *ot)
|
|||||||
/** \name Pick Select Operator
|
/** \name Pick Select Operator
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
bool PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
|
struct NearestParticleData {
|
||||||
|
PTCacheEditPoint *point;
|
||||||
|
PTCacheEditKey *key;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void nearest_key_fn(PEData *data, int point_index, int key_index, bool UNUSED(is_inside))
|
||||||
|
{
|
||||||
|
PTCacheEdit *edit = data->edit;
|
||||||
|
PTCacheEditPoint *point = edit->points + point_index;
|
||||||
|
PTCacheEditKey *key = point->keys + key_index;
|
||||||
|
|
||||||
|
struct NearestParticleData *user_data = data->user_data;
|
||||||
|
user_data->point = point;
|
||||||
|
user_data->key = key;
|
||||||
|
data->is_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool pe_nearest_point_and_key(bContext *C,
|
||||||
|
const int mval[2],
|
||||||
|
PTCacheEditPoint **r_point,
|
||||||
|
PTCacheEditKey **r_key)
|
||||||
|
{
|
||||||
|
struct NearestParticleData user_data = {NULL};
|
||||||
|
|
||||||
|
PEData data;
|
||||||
|
PE_set_view3d_data(C, &data);
|
||||||
|
data.mval = mval;
|
||||||
|
data.rad = ED_view3d_select_dist_px();
|
||||||
|
|
||||||
|
data.user_data = &user_data;
|
||||||
|
for_mouse_hit_keys(&data, nearest_key_fn, PSEL_NEAREST);
|
||||||
|
bool found = data.is_changed;
|
||||||
|
PE_data_free(&data);
|
||||||
|
|
||||||
|
*r_point = user_data.point;
|
||||||
|
*r_key = user_data.key;
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PE_mouse_particles(bContext *C, const int mval[2], const struct SelectPick_Params *params)
|
||||||
{
|
{
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
POINT_P;
|
|
||||||
KEY_K;
|
|
||||||
|
|
||||||
PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
|
PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
|
||||||
|
|
||||||
@@ -1876,39 +1875,61 @@ bool PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool desele
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extend && !deselect && !toggle) {
|
PTCacheEditPoint *point;
|
||||||
LOOP_VISIBLE_POINTS {
|
PTCacheEditKey *key;
|
||||||
LOOP_SELECTED_KEYS {
|
|
||||||
key->flag &= ~PEK_SELECT;
|
bool changed = false;
|
||||||
|
const bool found = pe_nearest_point_and_key(C, mval, &point, &key);
|
||||||
|
|
||||||
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
|
changed |= PE_deselect_all_visible_ex(edit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
switch (params->sel_op) {
|
||||||
|
case SEL_OP_ADD: {
|
||||||
|
if ((key->flag & PEK_SELECT) == 0) {
|
||||||
|
key->flag |= PEK_SELECT;
|
||||||
|
point->flag |= PEP_EDIT_RECALC;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SUB: {
|
||||||
|
if ((key->flag & PEK_SELECT) != 0) {
|
||||||
|
key->flag &= ~PEK_SELECT;
|
||||||
|
point->flag |= PEP_EDIT_RECALC;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_XOR: {
|
||||||
|
key->flag ^= PEK_SELECT;
|
||||||
point->flag |= PEP_EDIT_RECALC;
|
point->flag |= PEP_EDIT_RECALC;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
if ((key->flag & PEK_SELECT) == 0) {
|
||||||
|
key->flag |= PEK_SELECT;
|
||||||
|
point->flag |= PEP_EDIT_RECALC;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PEData data;
|
if (changed) {
|
||||||
PE_set_view3d_data(C, &data);
|
PE_update_selection(depsgraph, scene, ob, 1);
|
||||||
data.mval = mval;
|
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
|
||||||
data.rad = ED_view3d_select_dist_px();
|
|
||||||
|
|
||||||
/* 1 = nearest only */
|
|
||||||
if (extend) {
|
|
||||||
for_mouse_hit_keys(&data, extend_key_select, PSEL_NEAREST);
|
|
||||||
}
|
|
||||||
else if (deselect) {
|
|
||||||
for_mouse_hit_keys(&data, deselect_key_select, PSEL_NEAREST);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for_mouse_hit_keys(&data, toggle_key_select, PSEL_NEAREST);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.is_changed) {
|
return changed || found;
|
||||||
PE_update_selection(data.depsgraph, scene, ob, 1);
|
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
|
|
||||||
}
|
|
||||||
|
|
||||||
PE_data_free(&data);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|||||||
@@ -1554,9 +1554,7 @@ static Base *object_mouse_select_menu(bContext *C,
|
|||||||
const GPUSelectResult *buffer,
|
const GPUSelectResult *buffer,
|
||||||
const int hits,
|
const int hits,
|
||||||
const int mval[2],
|
const int mval[2],
|
||||||
bool extend,
|
const struct SelectPick_Params *params)
|
||||||
bool deselect,
|
|
||||||
bool toggle)
|
|
||||||
{
|
{
|
||||||
short baseCount = 0;
|
short baseCount = 0;
|
||||||
bool ok;
|
bool ok;
|
||||||
@@ -1625,9 +1623,9 @@ static Base *object_mouse_select_menu(bContext *C,
|
|||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
|
|
||||||
WM_operator_properties_create_ptr(&ptr, ot);
|
WM_operator_properties_create_ptr(&ptr, ot);
|
||||||
RNA_boolean_set(&ptr, "extend", extend);
|
RNA_boolean_set(&ptr, "extend", params->sel_op == SEL_OP_ADD);
|
||||||
RNA_boolean_set(&ptr, "deselect", deselect);
|
RNA_boolean_set(&ptr, "deselect", params->sel_op == SEL_OP_SUB);
|
||||||
RNA_boolean_set(&ptr, "toggle", toggle);
|
RNA_boolean_set(&ptr, "toggle", params->sel_op == SEL_OP_XOR);
|
||||||
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, NULL);
|
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, NULL);
|
||||||
WM_operator_properties_free(&ptr);
|
WM_operator_properties_free(&ptr);
|
||||||
|
|
||||||
@@ -1638,9 +1636,12 @@ static Base *object_mouse_select_menu(bContext *C,
|
|||||||
static int bone_select_menu_exec(bContext *C, wmOperator *op)
|
static int bone_select_menu_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
const int name_index = RNA_enum_get(op->ptr, "name");
|
const int name_index = RNA_enum_get(op->ptr, "name");
|
||||||
const bool extend = RNA_boolean_get(op->ptr, "extend");
|
|
||||||
const bool deselect = RNA_boolean_get(op->ptr, "deselect");
|
const struct SelectPick_Params params = {
|
||||||
const bool toggle = RNA_boolean_get(op->ptr, "toggle");
|
.sel_op = ED_select_op_from_booleans(RNA_boolean_get(op->ptr, "extend"),
|
||||||
|
RNA_boolean_get(op->ptr, "deselect"),
|
||||||
|
RNA_boolean_get(op->ptr, "toggle")),
|
||||||
|
};
|
||||||
|
|
||||||
View3D *v3d = CTX_wm_view3d(C);
|
View3D *v3d = CTX_wm_view3d(C);
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
@@ -1656,12 +1657,11 @@ static int bone_select_menu_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
if (basact->object->mode == OB_MODE_EDIT) {
|
if (basact->object->mode == OB_MODE_EDIT) {
|
||||||
EditBone *ebone = (EditBone *)object_mouse_select_menu_data[name_index].item_ptr;
|
EditBone *ebone = (EditBone *)object_mouse_select_menu_data[name_index].item_ptr;
|
||||||
ED_armature_edit_select_pick_bone(C, basact, ebone, BONE_SELECTED, extend, deselect, toggle);
|
ED_armature_edit_select_pick_bone(C, basact, ebone, BONE_SELECTED, ¶ms);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bPoseChannel *pchan = (bPoseChannel *)object_mouse_select_menu_data[name_index].item_ptr;
|
bPoseChannel *pchan = (bPoseChannel *)object_mouse_select_menu_data[name_index].item_ptr;
|
||||||
ED_armature_pose_select_pick_bone(
|
ED_armature_pose_select_pick_bone(view_layer, v3d, basact->object, pchan->bone, ¶ms);
|
||||||
view_layer, v3d, basact->object, pchan->bone, extend, deselect, toggle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Weak but ensures we activate the menu again before using the enum. */
|
/* Weak but ensures we activate the menu again before using the enum. */
|
||||||
@@ -1730,9 +1730,7 @@ static bool bone_mouse_select_menu(bContext *C,
|
|||||||
const GPUSelectResult *buffer,
|
const GPUSelectResult *buffer,
|
||||||
const int hits,
|
const int hits,
|
||||||
const bool is_editmode,
|
const bool is_editmode,
|
||||||
const bool extend,
|
const struct SelectPick_Params *params)
|
||||||
const bool deselect,
|
|
||||||
const bool toggle)
|
|
||||||
{
|
{
|
||||||
BLI_assert(buffer);
|
BLI_assert(buffer);
|
||||||
|
|
||||||
@@ -1848,9 +1846,9 @@ static bool bone_mouse_select_menu(bContext *C,
|
|||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
|
|
||||||
WM_operator_properties_create_ptr(&ptr, ot);
|
WM_operator_properties_create_ptr(&ptr, ot);
|
||||||
RNA_boolean_set(&ptr, "extend", extend);
|
RNA_boolean_set(&ptr, "extend", params->sel_op == SEL_OP_ADD);
|
||||||
RNA_boolean_set(&ptr, "deselect", deselect);
|
RNA_boolean_set(&ptr, "deselect", params->sel_op == SEL_OP_SUB);
|
||||||
RNA_boolean_set(&ptr, "toggle", toggle);
|
RNA_boolean_set(&ptr, "toggle", params->sel_op == SEL_OP_XOR);
|
||||||
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, NULL);
|
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, NULL);
|
||||||
WM_operator_properties_free(&ptr);
|
WM_operator_properties_free(&ptr);
|
||||||
|
|
||||||
@@ -2238,12 +2236,9 @@ static void deselect_all_tracks(MovieTracking *tracking)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mval is region coords */
|
|
||||||
static bool ed_object_select_pick(bContext *C,
|
static bool ed_object_select_pick(bContext *C,
|
||||||
const int mval[2],
|
const int mval[2],
|
||||||
bool extend,
|
const struct SelectPick_Params *params,
|
||||||
bool deselect,
|
|
||||||
bool toggle,
|
|
||||||
bool obcenter,
|
bool obcenter,
|
||||||
bool enumerate,
|
bool enumerate,
|
||||||
bool object)
|
bool object)
|
||||||
@@ -2290,7 +2285,7 @@ static bool ed_object_select_pick(bContext *C,
|
|||||||
|
|
||||||
/* NOTE: shift+alt goes to group-flush-selecting. */
|
/* NOTE: shift+alt goes to group-flush-selecting. */
|
||||||
if (enumerate) {
|
if (enumerate) {
|
||||||
basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, extend, deselect, toggle);
|
basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, params);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
base = startbase;
|
base = startbase;
|
||||||
@@ -2356,12 +2351,11 @@ static bool ed_object_select_pick(bContext *C,
|
|||||||
|
|
||||||
/* NOTE: shift+alt goes to group-flush-selecting. */
|
/* NOTE: shift+alt goes to group-flush-selecting. */
|
||||||
if (enumerate) {
|
if (enumerate) {
|
||||||
if (has_bones &&
|
if (has_bones && bone_mouse_select_menu(C, buffer, hits, false, params)) {
|
||||||
bone_mouse_select_menu(C, buffer, hits, false, extend, deselect, toggle)) {
|
|
||||||
basact = NULL;
|
basact = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
basact = object_mouse_select_menu(C, &vc, buffer, hits, mval, extend, deselect, toggle);
|
basact = object_mouse_select_menu(C, &vc, buffer, hits, mval, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2388,6 +2382,7 @@ static bool ed_object_select_pick(bContext *C,
|
|||||||
* in height word, this buffer value belongs to camera. not to bundle
|
* in height word, this buffer value belongs to camera. not to bundle
|
||||||
*/
|
*/
|
||||||
if (hitresult & 0xFFFF0000) {
|
if (hitresult & 0xFFFF0000) {
|
||||||
|
const bool extend = params->sel_op == SEL_OP_ADD;
|
||||||
MovieTracking *tracking = &clip->tracking;
|
MovieTracking *tracking = &clip->tracking;
|
||||||
ListBase *tracksbase;
|
ListBase *tracksbase;
|
||||||
MovieTrackingTrack *track;
|
MovieTrackingTrack *track;
|
||||||
@@ -2432,15 +2427,8 @@ static bool ed_object_select_pick(bContext *C,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ED_armature_pose_select_pick_with_buffer(view_layer,
|
else if (ED_armature_pose_select_pick_with_buffer(
|
||||||
v3d,
|
view_layer, v3d, basact, buffer, hits, params, do_nearest)) {
|
||||||
basact,
|
|
||||||
buffer,
|
|
||||||
hits,
|
|
||||||
extend,
|
|
||||||
deselect,
|
|
||||||
toggle,
|
|
||||||
do_nearest)) {
|
|
||||||
/* then bone is found */
|
/* then bone is found */
|
||||||
|
|
||||||
/* we make the armature selected:
|
/* we make the armature selected:
|
||||||
@@ -2502,6 +2490,22 @@ static bool ed_object_select_pick(bContext *C,
|
|||||||
/* Ensure code above doesn't change the active base. */
|
/* Ensure code above doesn't change the active base. */
|
||||||
BLI_assert(oldbasact == (vc.obact ? BASACT(view_layer) : NULL));
|
BLI_assert(oldbasact == (vc.obact ? BASACT(view_layer) : NULL));
|
||||||
|
|
||||||
|
if (vc.obedit) {
|
||||||
|
/* Edit-mode, pass. */
|
||||||
|
}
|
||||||
|
else if (is_pose_mode && (basact && (basact->object->mode & OB_MODE_POSE))) {
|
||||||
|
/* Pose-mode, pass (or moved into pose mode). */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Object-mode. */
|
||||||
|
const bool found = (basact != NULL);
|
||||||
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
|
/* `basact` may be NULL. */
|
||||||
|
retval |= object_deselect_all_except(view_layer, basact);
|
||||||
|
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* so, do we have something selected? */
|
/* so, do we have something selected? */
|
||||||
if (basact) {
|
if (basact) {
|
||||||
retval = true;
|
retval = true;
|
||||||
@@ -2514,28 +2518,39 @@ static bool ed_object_select_pick(bContext *C,
|
|||||||
/* also prevent making it active on mouse selection */
|
/* also prevent making it active on mouse selection */
|
||||||
else if (BASE_SELECTABLE(v3d, basact)) {
|
else if (BASE_SELECTABLE(v3d, basact)) {
|
||||||
const bool use_activate_selected_base = (oldbasact != basact) && (is_obedit == false);
|
const bool use_activate_selected_base = (oldbasact != basact) && (is_obedit == false);
|
||||||
if (extend) {
|
|
||||||
ED_object_base_select(basact, BA_SELECT);
|
switch (params->sel_op) {
|
||||||
}
|
case SEL_OP_ADD: {
|
||||||
else if (deselect) {
|
ED_object_base_select(basact, BA_SELECT);
|
||||||
ED_object_base_select(basact, BA_DESELECT);
|
break;
|
||||||
}
|
}
|
||||||
else if (toggle) {
|
case SEL_OP_SUB: {
|
||||||
if (basact->flag & BASE_SELECTED) {
|
ED_object_base_select(basact, BA_DESELECT);
|
||||||
/* Keep selected if the base is to be activated. */
|
break;
|
||||||
if (use_activate_selected_base == false) {
|
}
|
||||||
ED_object_base_select(basact, BA_DESELECT);
|
case SEL_OP_XOR: {
|
||||||
|
if (basact->flag & BASE_SELECTED) {
|
||||||
|
/* Keep selected if the base is to be activated. */
|
||||||
|
if (use_activate_selected_base == false) {
|
||||||
|
ED_object_base_select(basact, BA_DESELECT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ED_object_base_select(basact, BA_SELECT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else {
|
case SEL_OP_SET: {
|
||||||
ED_object_base_select(basact, BA_SELECT);
|
/* When enabled, this puts other objects out of multi pose-mode. */
|
||||||
|
if (is_pose_mode == false || (basact->object->mode & OB_MODE_POSE) == 0) {
|
||||||
|
object_deselect_all_except(view_layer, basact);
|
||||||
|
ED_object_base_select(basact, BA_SELECT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case SEL_OP_AND: {
|
||||||
else {
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
/* When enabled, this puts other objects out of multi pose-mode. */
|
break;
|
||||||
if (is_pose_mode == false || (basact->object->mode & OB_MODE_POSE) == 0) {
|
|
||||||
object_deselect_all_except(view_layer, basact);
|
|
||||||
ED_object_base_select(basact, BA_SELECT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2571,13 +2586,28 @@ static bool ed_object_select_pick(bContext *C,
|
|||||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
|
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (retval) {
|
||||||
|
if (vc.obact && vc.obact->mode & OB_MODE_POSE) {
|
||||||
|
ED_outliner_select_sync_from_pose_bone_tag(C);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ED_outliner_select_sync_from_object_tag(C);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mouse selection in weight paint */
|
/**
|
||||||
/* gets called via generic mouse select operator */
|
* Mouse selection in weight paint.
|
||||||
static bool ed_wpaint_vertex_select_pick(
|
* Called via generic mouse select operator.
|
||||||
bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, Object *obact)
|
*
|
||||||
|
* \return True when pick finds an element or the selection changed.
|
||||||
|
*/
|
||||||
|
static bool ed_wpaint_vertex_select_pick(bContext *C,
|
||||||
|
const int mval[2],
|
||||||
|
const struct SelectPick_Params *params,
|
||||||
|
Object *obact)
|
||||||
{
|
{
|
||||||
View3D *v3d = CTX_wm_view3d(C);
|
View3D *v3d = CTX_wm_view3d(C);
|
||||||
const bool use_zbuf = !XRAY_ENABLED(v3d);
|
const bool use_zbuf = !XRAY_ENABLED(v3d);
|
||||||
@@ -2585,21 +2615,38 @@ static bool ed_wpaint_vertex_select_pick(
|
|||||||
Mesh *me = obact->data; /* already checked for NULL */
|
Mesh *me = obact->data; /* already checked for NULL */
|
||||||
uint index = 0;
|
uint index = 0;
|
||||||
MVert *mv;
|
MVert *mv;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
if (ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index)) {
|
bool found = ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index);
|
||||||
|
|
||||||
|
if ((params->sel_op == SEL_OP_SET) && (found || params->deselect_all)) {
|
||||||
|
changed |= paintface_deselect_all_visible(C, obact, SEL_DESELECT, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
mv = &me->mvert[index];
|
mv = &me->mvert[index];
|
||||||
if (extend) {
|
switch (params->sel_op) {
|
||||||
mv->flag |= SELECT;
|
case SEL_OP_ADD: {
|
||||||
}
|
mv->flag |= SELECT;
|
||||||
else if (deselect) {
|
break;
|
||||||
mv->flag &= ~SELECT;
|
}
|
||||||
}
|
case SEL_OP_SUB: {
|
||||||
else if (toggle) {
|
mv->flag &= ~SELECT;
|
||||||
mv->flag ^= SELECT;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
case SEL_OP_XOR: {
|
||||||
paintvert_deselect_all_visible(obact, SEL_DESELECT, false);
|
mv->flag ^= SELECT;
|
||||||
mv->flag |= SELECT;
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_SET: {
|
||||||
|
paintvert_deselect_all_visible(obact, SEL_DESELECT, false);
|
||||||
|
mv->flag |= SELECT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SEL_OP_AND: {
|
||||||
|
BLI_assert_unreachable(); /* Doesn't make sense for picking. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update mselect */
|
/* update mselect */
|
||||||
@@ -2611,10 +2658,15 @@ static bool ed_wpaint_vertex_select_pick(
|
|||||||
}
|
}
|
||||||
|
|
||||||
paintvert_flush_flags(obact);
|
paintvert_flush_flags(obact);
|
||||||
paintvert_tag_select_update(C, obact);
|
|
||||||
return true;
|
changed = true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
if (changed) {
|
||||||
|
paintvert_tag_select_update(C, obact);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int view3d_select_exec(bContext *C, wmOperator *op)
|
static int view3d_select_exec(bContext *C, wmOperator *op)
|
||||||
@@ -2622,10 +2674,13 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
|
|||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
Object *obedit = CTX_data_edit_object(C);
|
Object *obedit = CTX_data_edit_object(C);
|
||||||
Object *obact = CTX_data_active_object(C);
|
Object *obact = CTX_data_active_object(C);
|
||||||
bool extend = RNA_boolean_get(op->ptr, "extend");
|
const struct SelectPick_Params params = {
|
||||||
bool deselect = RNA_boolean_get(op->ptr, "deselect");
|
.sel_op = ED_select_op_from_booleans(RNA_boolean_get(op->ptr, "extend"),
|
||||||
bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
|
RNA_boolean_get(op->ptr, "deselect"),
|
||||||
bool toggle = RNA_boolean_get(op->ptr, "toggle");
|
RNA_boolean_get(op->ptr, "toggle")),
|
||||||
|
.deselect_all = RNA_boolean_get(op->ptr, "deselect_all"),
|
||||||
|
|
||||||
|
};
|
||||||
bool center = RNA_boolean_get(op->ptr, "center");
|
bool center = RNA_boolean_get(op->ptr, "center");
|
||||||
bool enumerate = RNA_boolean_get(op->ptr, "enumerate");
|
bool enumerate = RNA_boolean_get(op->ptr, "enumerate");
|
||||||
/* Only force object select for edit-mode to support vertex parenting,
|
/* Only force object select for edit-mode to support vertex parenting,
|
||||||
@@ -2656,10 +2711,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
if (obedit && object == false) {
|
if (obedit && object == false) {
|
||||||
if (obedit->type == OB_MESH) {
|
if (obedit->type == OB_MESH) {
|
||||||
retval = EDBM_select_pick(C, location, extend, deselect, toggle);
|
retval = EDBM_select_pick(C, location, ¶ms);
|
||||||
if (!retval && deselect_all) {
|
|
||||||
retval = EDBM_mesh_deselect_all_multi(C);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (obedit->type == OB_ARMATURE) {
|
else if (obedit->type == OB_ARMATURE) {
|
||||||
if (enumerate) {
|
if (enumerate) {
|
||||||
@@ -2676,90 +2728,36 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
false);
|
false);
|
||||||
retval = bone_mouse_select_menu(C, buffer, hits, true, extend, deselect, toggle);
|
retval = bone_mouse_select_menu(C, buffer, hits, true, ¶ms);
|
||||||
}
|
}
|
||||||
if (!retval) {
|
if (!retval) {
|
||||||
retval = ED_armature_edit_select_pick(C, location, extend, deselect, toggle);
|
retval = ED_armature_edit_select_pick(C, location, ¶ms);
|
||||||
}
|
|
||||||
|
|
||||||
if (!retval && deselect_all) {
|
|
||||||
retval = ED_armature_edit_deselect_all_visible_multi(C);
|
|
||||||
}
|
|
||||||
if (retval) {
|
|
||||||
ED_outliner_select_sync_from_edit_bone_tag(C);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (obedit->type == OB_LATTICE) {
|
else if (obedit->type == OB_LATTICE) {
|
||||||
retval = ED_lattice_select_pick(C, location, extend, deselect, toggle);
|
retval = ED_lattice_select_pick(C, location, ¶ms);
|
||||||
if (!retval && deselect_all) {
|
|
||||||
retval = ED_lattice_deselect_all_multi(C);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
|
else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
|
||||||
retval = ED_curve_editnurb_select_pick(C, location, extend, deselect, toggle);
|
retval = ED_curve_editnurb_select_pick(C, location, ¶ms);
|
||||||
if (!retval && deselect_all) {
|
|
||||||
retval = ED_curve_deselect_all_multi(C);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (obedit->type == OB_MBALL) {
|
else if (obedit->type == OB_MBALL) {
|
||||||
retval = ED_mball_select_pick(C, location, extend, deselect, toggle);
|
retval = ED_mball_select_pick(C, location, ¶ms);
|
||||||
if (!retval && deselect_all) {
|
|
||||||
retval = ED_mball_deselect_all_multi(C);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (obedit->type == OB_FONT) {
|
else if (obedit->type == OB_FONT) {
|
||||||
retval = ED_curve_editfont_select_pick(C, location, extend, deselect, toggle);
|
retval = ED_curve_editfont_select_pick(C, location, ¶ms);
|
||||||
if (!retval && deselect_all) {
|
|
||||||
/* pass */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (retval) {
|
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
|
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
|
||||||
retval = PE_mouse_particles(C, location, extend, deselect, toggle);
|
retval = PE_mouse_particles(C, location, ¶ms);
|
||||||
if (!retval && deselect_all) {
|
|
||||||
retval = PE_deselect_all_visible(C);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (obact && BKE_paint_select_face_test(obact)) {
|
else if (obact && BKE_paint_select_face_test(obact)) {
|
||||||
retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle);
|
retval = paintface_mouse_select(C, location, ¶ms, obact);
|
||||||
if (!retval && deselect_all) {
|
|
||||||
retval = paintface_deselect_all_visible(C, CTX_data_active_object(C), SEL_DESELECT, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (BKE_paint_select_vert_test(obact)) {
|
else if (BKE_paint_select_vert_test(obact)) {
|
||||||
retval = ed_wpaint_vertex_select_pick(C, location, extend, deselect, toggle, obact);
|
retval = ed_wpaint_vertex_select_pick(C, location, ¶ms, obact);
|
||||||
if (!retval && deselect_all) {
|
|
||||||
retval = paintvert_deselect_all_visible(obact, SEL_DESELECT, false);
|
|
||||||
if (retval) {
|
|
||||||
paintvert_tag_select_update(C, obact);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
retval = ed_object_select_pick(
|
retval = ed_object_select_pick(C, location, ¶ms, center, enumerate, object);
|
||||||
C, location, extend, deselect, toggle, center, enumerate, object);
|
|
||||||
if (!retval && deselect_all) {
|
|
||||||
if (ED_pose_object_from_context(C)) {
|
|
||||||
retval = ED_pose_deselect_all_multi(C, SEL_DESELECT, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
retval = ED_object_base_deselect_all(
|
|
||||||
CTX_data_view_layer(C), CTX_wm_view3d(C), SEL_DESELECT);
|
|
||||||
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retval) {
|
|
||||||
if (obact && obact->mode & OB_MODE_POSE) {
|
|
||||||
ED_outliner_select_sync_from_pose_bone_tag(C);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ED_outliner_select_sync_from_object_tag(C);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass-through allows tweaks
|
/* Pass-through allows tweaks
|
||||||
|
|||||||
@@ -112,3 +112,17 @@ bool ED_select_similar_compare_float_tree(const KDTree_1d *tree,
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eSelectOp ED_select_op_from_booleans(const bool extend, const bool deselect, const bool toggle)
|
||||||
|
{
|
||||||
|
if (extend) {
|
||||||
|
return SEL_OP_ADD;
|
||||||
|
}
|
||||||
|
if (deselect) {
|
||||||
|
return SEL_OP_SUB;
|
||||||
|
}
|
||||||
|
if (toggle) {
|
||||||
|
return SEL_OP_XOR;
|
||||||
|
}
|
||||||
|
return SEL_OP_SET;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user