Fix T63125: Gpencil: bones cannot be selected in weightpaint mode
Some underlying functionality was not ready for greasepencil: - BKE_modifiers_get_virtual_modifierlist (now introduce dedicated BKE_gpencil_modifiers_get_virtual_modifierlist) - BKE_modifiers_is_deformed_by_armature - checks in drawing code - checks in (pose) selection code A couple of changes to make this work: - `eGpencilModifierType_Armature` has to be respected (not only `eModifierType_Armature`) - `OB_MODE_WEIGHT_GPENCIL` has to be respected (not only `OB_MODE_WEIGHT_PAINT`) -- (now use new `OB_MODE_ALL_WEIGHT_PAINT`) - `gpencil_weightmode_toggle_exec` now shares functionality from `wpaint_mode_toggle_exec` -- moved to new `ED_object_posemode_set_for_weight_paint` This patch will also set the context member "weight_paint_object" for greasepencil (otherwise some appropriate pose operators wont work when in weightpaint mode) Reviewed By: campbellbarton Maniphest Tasks: T63125 Differential Revision: https://developer.blender.org/D8483
This commit is contained in:
parent
a505a85873
commit
f00cb93dbe
Notes:
blender-bot
2023-02-14 03:09:57 +01:00
Referenced by commit 952d6663e0
, Fix modifier deform by armature check ignoring virtual modifiers
Referenced by issue #63125, Can't select individual bones when in weight paint mode for grease pencil
|
@ -292,6 +292,14 @@ void BKE_gpencil_modifiers_foreach_tex_link(struct Object *ob,
|
|||
GreasePencilTexWalkFunc walk,
|
||||
void *userData);
|
||||
|
||||
typedef struct GpencilVirtualModifierData {
|
||||
ArmatureGpencilModifierData amd;
|
||||
LatticeGpencilModifierData lmd;
|
||||
} GpencilVirtualModifierData;
|
||||
|
||||
struct GpencilModifierData *BKE_gpencil_modifiers_get_virtual_modifierlist(
|
||||
const struct Object *ob, struct GpencilVirtualModifierData *data);
|
||||
|
||||
bool BKE_gpencil_has_geometry_modifiers(struct Object *ob);
|
||||
bool BKE_gpencil_has_time_modifiers(struct Object *ob);
|
||||
bool BKE_gpencil_has_transform_modifiers(struct Object *ob);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
@ -57,6 +58,10 @@
|
|||
|
||||
static CLG_LogRef LOG = {"bke.gpencil_modifier"};
|
||||
static GpencilModifierTypeInfo *modifier_gpencil_types[NUM_GREASEPENCIL_MODIFIER_TYPES] = {NULL};
|
||||
#if 0
|
||||
/* Note that GPencil actually does not support these atm, but might do in the future. */
|
||||
static GpencilVirtualModifierData virtualModifierCommonData;
|
||||
#endif
|
||||
|
||||
/* Lattice Modifier ---------------------------------- */
|
||||
/* Usually, evaluation of the lattice modifier is self-contained.
|
||||
|
@ -110,6 +115,34 @@ void BKE_gpencil_lattice_clear(Object *ob)
|
|||
/* *************************************************** */
|
||||
/* Modifier Methods - Evaluation Loops, etc. */
|
||||
|
||||
/* This is to include things that are not modifiers in the evaluation of the modifier stack, for
|
||||
* example parenting to an armature or lattice without having a real modifier. */
|
||||
GpencilModifierData *BKE_gpencil_modifiers_get_virtual_modifierlist(
|
||||
const Object *ob, GpencilVirtualModifierData *UNUSED(virtualModifierData))
|
||||
{
|
||||
GpencilModifierData *md = ob->greasepencil_modifiers.first;
|
||||
|
||||
#if 0
|
||||
/* Note that GPencil actually does not support these atm, but might do in the future. */
|
||||
*virtualModifierData = virtualModifierCommonData;
|
||||
if (ob->parent) {
|
||||
if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
|
||||
virtualModifierData->amd.object = ob->parent;
|
||||
virtualModifierData->amd.modifier.next = md;
|
||||
virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag;
|
||||
md = &virtualModifierData->amd.modifier;
|
||||
}
|
||||
else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
|
||||
virtualModifierData->lmd.object = ob->parent;
|
||||
virtualModifierData->lmd.modifier.next = md;
|
||||
md = &virtualModifierData->lmd.modifier;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if object has grease pencil Geometry modifiers.
|
||||
* \param ob: Grease pencil object
|
||||
|
@ -229,6 +262,22 @@ void BKE_gpencil_modifier_init(void)
|
|||
{
|
||||
/* Initialize modifier types */
|
||||
gpencil_modifier_type_init(modifier_gpencil_types); /* MOD_gpencil_util.c */
|
||||
|
||||
#if 0
|
||||
/* Note that GPencil actually does not support these atm, but might do in the future. */
|
||||
/* Initialize global cmmon storage used for virtual modifier list */
|
||||
GpencilModifierData *md;
|
||||
md = BKE_gpencil_modifier_new(eGpencilModifierType_Armature);
|
||||
virtualModifierCommonData.amd = *((ArmatureGpencilModifierData *)md);
|
||||
BKE_gpencil_modifier_free(md);
|
||||
|
||||
md = BKE_gpencil_modifier_new(eGpencilModifierType_Lattice);
|
||||
virtualModifierCommonData.lmd = *((LatticeGpencilModifierData *)md);
|
||||
BKE_gpencil_modifier_free(md);
|
||||
|
||||
virtualModifierCommonData.amd.modifier.mode |= eGpencilModifierMode_Virtual;
|
||||
virtualModifierCommonData.lmd.modifier.mode |= eGpencilModifierMode_Virtual;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
@ -53,6 +54,7 @@
|
|||
#include "BKE_editmesh.h"
|
||||
#include "BKE_editmesh_cache.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_gpencil_modifier.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -653,9 +655,7 @@ ModifierData *BKE_modifier_get_last_preview(struct Scene *scene,
|
|||
ModifierData *BKE_modifiers_get_virtual_modifierlist(const Object *ob,
|
||||
VirtualModifierData *virtualModifierData)
|
||||
{
|
||||
ModifierData *md;
|
||||
|
||||
md = ob->modifiers.first;
|
||||
ModifierData *md = ob->modifiers.first;
|
||||
|
||||
*virtualModifierData = virtualModifierCommonData;
|
||||
|
||||
|
@ -700,22 +700,46 @@ ModifierData *BKE_modifiers_get_virtual_modifierlist(const Object *ob,
|
|||
*/
|
||||
Object *BKE_modifiers_is_deformed_by_armature(Object *ob)
|
||||
{
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
|
||||
ArmatureModifierData *amd = NULL;
|
||||
if (ob->type == OB_GPENCIL) {
|
||||
GpencilVirtualModifierData gpencilvirtualModifierData;
|
||||
ArmatureGpencilModifierData *agmd = NULL;
|
||||
GpencilModifierData *gmd = BKE_gpencil_modifiers_get_virtual_modifierlist(
|
||||
ob, &gpencilvirtualModifierData);
|
||||
gmd = ob->greasepencil_modifiers.first;
|
||||
|
||||
/* return the first selected armature, this lets us use multiple armatures */
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
amd = (ArmatureModifierData *)md;
|
||||
if (amd->object && (amd->object->base_flag & BASE_SELECTED)) {
|
||||
return amd->object;
|
||||
/* return the first selected armature, this lets us use multiple armatures */
|
||||
for (; gmd; gmd = gmd->next) {
|
||||
if (gmd->type == eGpencilModifierType_Armature) {
|
||||
agmd = (ArmatureGpencilModifierData *)gmd;
|
||||
if (agmd->object && (agmd->object->base_flag & BASE_SELECTED)) {
|
||||
return agmd->object;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If we're still here then return the last armature. */
|
||||
if (agmd) {
|
||||
return agmd->object;
|
||||
}
|
||||
}
|
||||
else {
|
||||
VirtualModifierData virtualModifierData;
|
||||
ArmatureModifierData *amd = NULL;
|
||||
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
|
||||
md = ob->modifiers.first;
|
||||
|
||||
if (amd) { /* if we're still here then return the last armature */
|
||||
return amd->object;
|
||||
/* return the first selected armature, this lets us use multiple armatures */
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
amd = (ArmatureModifierData *)md;
|
||||
if (amd->object && (amd->object->base_flag & BASE_SELECTED)) {
|
||||
return amd->object;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If we're still here then return the last armature. */
|
||||
if (amd) {
|
||||
return amd->object;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -113,7 +113,7 @@ bool OVERLAY_armature_is_pose_mode(Object *ob, const DRWContextState *draw_ctx)
|
|||
}
|
||||
|
||||
/* Armature parent is also handled by pose mode engine. */
|
||||
if ((active_ob != NULL) && ((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) != 0)) {
|
||||
if ((active_ob != NULL) && (draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
|
||||
if (ob == draw_ctx->object_pose) {
|
||||
return true;
|
||||
}
|
||||
|
@ -2000,7 +2000,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
|
|||
(scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) == 0) ||
|
||||
/* Allow selection when in weight-paint mode
|
||||
* (selection code ensures this wont become active). */
|
||||
((draw_ctx->object_mode == OB_MODE_WEIGHT_PAINT) &&
|
||||
((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) &&
|
||||
(draw_ctx->object_pose != NULL))))) &&
|
||||
DRW_state_is_select();
|
||||
|
||||
|
@ -2011,7 +2011,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
|
|||
}
|
||||
|
||||
/* In weight paint mode retrieve the vertex group lock status. */
|
||||
if ((draw_ctx->object_mode == OB_MODE_WEIGHT_PAINT) && (draw_ctx->object_pose == ob) &&
|
||||
if ((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) && (draw_ctx->object_pose == ob) &&
|
||||
(draw_ctx->obact != NULL)) {
|
||||
draw_locked_weights = true;
|
||||
|
||||
|
|
|
@ -451,7 +451,7 @@ static void drw_context_state_init(void)
|
|||
if (DST.draw_ctx.object_mode & OB_MODE_POSE) {
|
||||
DST.draw_ctx.object_pose = DST.draw_ctx.obact;
|
||||
}
|
||||
else if (DST.draw_ctx.object_mode & OB_MODE_WEIGHT_PAINT) {
|
||||
else if ((DST.draw_ctx.object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
|
||||
DST.draw_ctx.object_pose = BKE_object_pose_armature_get(DST.draw_ctx.obact);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "DNA_anim_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
|
@ -37,6 +38,7 @@
|
|||
#include "BKE_armature.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil_modifier.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
|
@ -172,7 +174,7 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
|
|||
* note, 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 - campbell */
|
||||
if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) {
|
||||
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) {
|
||||
|
@ -225,7 +227,7 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
|
|||
|
||||
if (ob_act) {
|
||||
/* in weightpaint we select the associated vertex group too */
|
||||
if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
|
||||
if (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) {
|
||||
if (nearBone == arm->act_bone) {
|
||||
ED_vgroup_select_by_name(ob_act, nearBone->name);
|
||||
DEG_id_tag_update(&ob_act->id, ID_RECALC_GEOMETRY);
|
||||
|
@ -261,17 +263,39 @@ void ED_armature_pose_select_in_wpaint_mode(ViewLayer *view_layer, Base *base_se
|
|||
{
|
||||
BLI_assert(base_select && (base_select->object->type == OB_ARMATURE));
|
||||
Object *ob_active = OBACT(view_layer);
|
||||
BLI_assert(ob_active && (ob_active->mode & OB_MODE_WEIGHT_PAINT));
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob_active, &virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
Object *ob_arm = amd->object;
|
||||
if (ob_arm != NULL) {
|
||||
Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
|
||||
if ((base_arm != NULL) && (base_arm != base_select) && (base_arm->flag & BASE_SELECTED)) {
|
||||
ED_object_base_select(base_arm, BA_DESELECT);
|
||||
BLI_assert(ob_active && (ob_active->mode & OB_MODE_ALL_WEIGHT_PAINT));
|
||||
|
||||
if (ob_active->type == OB_GPENCIL) {
|
||||
GpencilVirtualModifierData virtualModifierData;
|
||||
GpencilModifierData *md = BKE_gpencil_modifiers_get_virtual_modifierlist(ob_active,
|
||||
&virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eGpencilModifierType_Armature) {
|
||||
ArmatureGpencilModifierData *agmd = (ArmatureGpencilModifierData *)md;
|
||||
Object *ob_arm = agmd->object;
|
||||
if (ob_arm != NULL) {
|
||||
Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
|
||||
if ((base_arm != NULL) && (base_arm != base_select) &&
|
||||
(base_arm->flag & BASE_SELECTED)) {
|
||||
ED_object_base_select(base_arm, BA_DESELECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob_active, &virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
Object *ob_arm = amd->object;
|
||||
if (ob_arm != NULL) {
|
||||
Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
|
||||
if ((base_arm != NULL) && (base_arm != base_select) &&
|
||||
(base_arm->flag & BASE_SELECTED)) {
|
||||
ED_object_base_select(base_arm, BA_DESELECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
@ -52,7 +53,9 @@
|
|||
#include "BKE_global.h"
|
||||
#include "BKE_gpencil.h"
|
||||
#include "BKE_gpencil_geom.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_object.h"
|
||||
|
@ -75,6 +78,7 @@
|
|||
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "ED_armature.h"
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_outliner.h"
|
||||
|
@ -571,6 +575,8 @@ static int gpencil_weightmode_toggle_exec(bContext *C, wmOperator *op)
|
|||
gpd = ob->data;
|
||||
is_object = true;
|
||||
}
|
||||
const int mode_flag = OB_MODE_WEIGHT_GPENCIL;
|
||||
const bool is_mode_set = (ob->mode & mode_flag) != 0;
|
||||
|
||||
if (gpd == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
|
@ -593,6 +599,9 @@ static int gpencil_weightmode_toggle_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
ob->restore_mode = ob->mode;
|
||||
ob->mode = mode;
|
||||
|
||||
/* Prepare armature posemode. */
|
||||
ED_object_posemode_set_for_weight_paint(C, bmain, ob, is_mode_set);
|
||||
}
|
||||
|
||||
if (mode == OB_MODE_WEIGHT_GPENCIL) {
|
||||
|
|
|
@ -352,6 +352,11 @@ void ED_object_mode_generic_exit(struct Main *bmain,
|
|||
struct Object *ob);
|
||||
bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, struct Object *ob);
|
||||
|
||||
void ED_object_posemode_set_for_weight_paint(struct bContext *C,
|
||||
struct Main *bmain,
|
||||
struct Object *ob,
|
||||
const bool is_mode_set);
|
||||
|
||||
/* object_modifier.c */
|
||||
enum {
|
||||
MODIFIER_APPLY_DATA = 1,
|
||||
|
|
|
@ -29,7 +29,10 @@
|
|||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil_modifier.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_report.h"
|
||||
|
@ -304,6 +307,75 @@ static bool ed_object_mode_generic_exit_ex(struct Main *bmain,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* When locked, it's almost impossible to select the pose-object
|
||||
* then the mesh-object to enter weight paint mode.
|
||||
* Even when the object mode is not locked this is inconvenient - so allow in either case.
|
||||
*
|
||||
* In this case move our pose object in/out of pose mode.
|
||||
* This is in fits with the convention of selecting multiple objects and entering a mode.
|
||||
*/
|
||||
static void ed_object_posemode_set_for_weight_paint_ex(bContext *C,
|
||||
Main *bmain,
|
||||
Object *ob_arm,
|
||||
const bool is_mode_set)
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
||||
if (ob_arm != NULL) {
|
||||
const Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
|
||||
if (base_arm && BASE_VISIBLE(v3d, base_arm)) {
|
||||
if (is_mode_set) {
|
||||
if ((ob_arm->mode & OB_MODE_POSE) != 0) {
|
||||
ED_object_posemode_exit_ex(bmain, ob_arm);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Only check selected status when entering weight-paint mode
|
||||
* because we may have multiple armature objects.
|
||||
* Selecting one will de-select the other, which would leave it in pose-mode
|
||||
* when exiting weight paint mode. While usable, this looks like inconsistent
|
||||
* behavior from a user perspective. */
|
||||
if (base_arm->flag & BASE_SELECTED) {
|
||||
if ((ob_arm->mode & OB_MODE_POSE) == 0) {
|
||||
ED_object_posemode_enter_ex(bmain, ob_arm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ED_object_posemode_set_for_weight_paint(bContext *C,
|
||||
Main *bmain,
|
||||
Object *ob,
|
||||
const bool is_mode_set)
|
||||
{
|
||||
if (ob->type == OB_GPENCIL) {
|
||||
GpencilVirtualModifierData virtualModifierData;
|
||||
GpencilModifierData *md = BKE_gpencil_modifiers_get_virtual_modifierlist(ob,
|
||||
&virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eGpencilModifierType_Armature) {
|
||||
ArmatureGpencilModifierData *amd = (ArmatureGpencilModifierData *)md;
|
||||
Object *ob_arm = amd->object;
|
||||
ed_object_posemode_set_for_weight_paint_ex(C, bmain, ob_arm, is_mode_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
Object *ob_arm = amd->object;
|
||||
ed_object_posemode_set_for_weight_paint_ex(C, bmain, ob_arm, is_mode_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ED_object_mode_generic_exit(struct Main *bmain,
|
||||
struct Depsgraph *depsgraph,
|
||||
struct Scene *scene,
|
||||
|
|
|
@ -449,7 +449,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
|
|||
return 1;
|
||||
}
|
||||
if (CTX_data_equals(member, "weight_paint_object")) {
|
||||
if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) {
|
||||
if (obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT)) {
|
||||
CTX_data_id_pointer_set(result, &obact->id);
|
||||
}
|
||||
|
||||
|
|
|
@ -481,7 +481,7 @@ bool ED_operator_posemode(bContext *C)
|
|||
if (obact && !(obact->mode & OB_MODE_EDIT)) {
|
||||
Object *obpose;
|
||||
if ((obpose = BKE_object_pose_armature_get(obact))) {
|
||||
if ((obact == obpose) || (obact->mode & OB_MODE_WEIGHT_PAINT)) {
|
||||
if ((obact == obpose) || (obact->mode & OB_MODE_ALL_WEIGHT_PAINT)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1376,50 +1376,8 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
|
|||
BKE_paint_toolslots_brush_validate(bmain, &ts->wpaint->paint);
|
||||
}
|
||||
|
||||
/* When locked, it's almost impossible to select the pose-object
|
||||
* then the mesh-object to enter weight paint mode.
|
||||
* Even when the object mode is not locked this is inconvenient - so allow in either case.
|
||||
*
|
||||
* In this case move our pose object in/out of pose mode.
|
||||
* This is in fits with the convention of selecting multiple objects and entering a mode.
|
||||
*/
|
||||
{
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
|
||||
if (md != NULL) {
|
||||
/* Can be NULL. */
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
Object *ob_arm = amd->object;
|
||||
if (ob_arm != NULL) {
|
||||
const Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
|
||||
if (base_arm && BASE_VISIBLE(v3d, base_arm)) {
|
||||
if (is_mode_set) {
|
||||
if ((ob_arm->mode & OB_MODE_POSE) != 0) {
|
||||
ED_object_posemode_exit_ex(bmain, ob_arm);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Only check selected status when entering weight-paint mode
|
||||
* because we may have multiple armature objects.
|
||||
* Selecting one will de-select the other, which would leave it in pose-mode
|
||||
* when exiting weight paint mode. While usable, this looks like inconsistent
|
||||
* behavior from a user perspective. */
|
||||
if (base_arm->flag & BASE_SELECTED) {
|
||||
if ((ob_arm->mode & OB_MODE_POSE) == 0) {
|
||||
ED_object_posemode_enter_ex(bmain, ob_arm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Prepare armature posemode. */
|
||||
ED_object_posemode_set_for_weight_paint(C, bmain, ob, is_mode_set);
|
||||
|
||||
/* Weight-paint works by overriding colors in mesh,
|
||||
* so need to make sure we recalculate on enter and
|
||||
|
|
|
@ -2208,7 +2208,7 @@ static bool ed_object_select_pick(bContext *C,
|
|||
|
||||
/* In weight-paint, we use selected bone to select vertex-group,
|
||||
* so don't switch to new active object. */
|
||||
if (oldbasact && (oldbasact->object->mode & OB_MODE_WEIGHT_PAINT)) {
|
||||
if (oldbasact && (oldbasact->object->mode & OB_MODE_ALL_WEIGHT_PAINT)) {
|
||||
/* Prevent activating.
|
||||
* Selection causes this to be considered the 'active' pose in weight-paint mode.
|
||||
* Eventually this limitation may be removed.
|
||||
|
@ -2382,7 +2382,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
|
|||
bool object = (RNA_boolean_get(op->ptr, "object") &&
|
||||
(obedit || BKE_paint_select_elem_test(obact) ||
|
||||
/* so its possible to select bones in weight-paint mode (LMB select) */
|
||||
(obact && (obact->mode & OB_MODE_WEIGHT_PAINT) &&
|
||||
(obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT) &&
|
||||
BKE_object_pose_armature_get(obact))));
|
||||
|
||||
bool retval = false;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
|
@ -37,6 +38,7 @@
|
|||
#include "BKE_camera.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_gpencil_modifier.h"
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.h"
|
||||
|
@ -949,7 +951,7 @@ static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
|
|||
eV3DSelectObjectFilter ED_view3d_select_filter_from_mode(const Scene *scene, const Object *obact)
|
||||
{
|
||||
if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
|
||||
if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT) &&
|
||||
if (obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT) &&
|
||||
BKE_object_pose_armature_get((Object *)obact)) {
|
||||
return VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK;
|
||||
}
|
||||
|
@ -1053,18 +1055,33 @@ int view3d_opengl_select(ViewContext *vc,
|
|||
}
|
||||
case VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK: {
|
||||
Object *obact = vc->obact;
|
||||
BLI_assert(obact && (obact->mode & OB_MODE_WEIGHT_PAINT));
|
||||
|
||||
BLI_assert(obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT));
|
||||
/* While this uses 'alloca' in a loop (which we typically avoid),
|
||||
* the number of items is nearly always 1, maybe 2..3 in rare cases. */
|
||||
LinkNode *ob_pose_list = NULL;
|
||||
VirtualModifierData virtualModifierData;
|
||||
const ModifierData *md = BKE_modifiers_get_virtual_modifierlist(obact, &virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
if (amd->object && (amd->object->mode & OB_MODE_POSE)) {
|
||||
BLI_linklist_prepend_alloca(&ob_pose_list, amd->object);
|
||||
if (obact->type == OB_GPENCIL) {
|
||||
GpencilVirtualModifierData virtualModifierData;
|
||||
const GpencilModifierData *md = BKE_gpencil_modifiers_get_virtual_modifierlist(
|
||||
obact, &virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eGpencilModifierType_Armature) {
|
||||
ArmatureGpencilModifierData *agmd = (ArmatureGpencilModifierData *)md;
|
||||
if (agmd->object && (agmd->object->mode & OB_MODE_POSE)) {
|
||||
BLI_linklist_prepend_alloca(&ob_pose_list, agmd->object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
VirtualModifierData virtualModifierData;
|
||||
const ModifierData *md = BKE_modifiers_get_virtual_modifierlist(obact,
|
||||
&virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
if (amd->object && (amd->object->mode & OB_MODE_POSE)) {
|
||||
BLI_linklist_prepend_alloca(&ob_pose_list, amd->object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef enum GpencilModifierMode {
|
|||
eGpencilModifierMode_Render = (1 << 1),
|
||||
eGpencilModifierMode_Editmode = (1 << 2),
|
||||
eGpencilModifierMode_Expanded_DEPRECATED = (1 << 3),
|
||||
eGpencilModifierMode_Virtual = (1 << 4),
|
||||
} GpencilModifierMode;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -60,6 +60,9 @@ typedef enum eDrawType {
|
|||
/** Any mode that uses Object.sculpt. */
|
||||
#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)
|
||||
|
||||
/** Any mode that uses weightpaint. */
|
||||
#define OB_MODE_ALL_WEIGHT_PAINT (OB_MODE_WEIGHT_PAINT | OB_MODE_WEIGHT_GPENCIL)
|
||||
|
||||
/**
|
||||
* Any mode that has data or for Grease Pencil modes, we need to free when switching modes,
|
||||
* see: #ED_object_mode_generic_exit
|
||||
|
|
Loading…
Reference in New Issue