Пример #1
0
static void do_outliner_bone_select_recursive(bArmature *arm, Bone *bone_parent, bool select)
{
	Bone *bone;
	for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
		if (select && PBONE_SELECTABLE(arm, bone))
			bone->flag |= BONE_SELECTED;
		else
			bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
		do_outliner_bone_select_recursive(arm, bone, select);
	}
}
Пример #2
0
/* Utility method for changing the selection status of a bone */
void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
{
	bArmature *arm;

	/* sanity checks */
	// XXX: actually, we can probably still get away with no object - at most we have no updates
	if (ELEM4(NULL, ob, ob->pose, pchan, pchan->bone))
		return;
	
	arm = ob->data;
	
	/* can only change selection state if bone can be modified */
	if (PBONE_SELECTABLE(arm, pchan->bone)) {
		/* change selection state - activate too if selected */
		if (select) {
			pchan->bone->flag |= BONE_SELECTED;
			arm->act_bone = pchan->bone;
		}
		else {
			pchan->bone->flag &= ~BONE_SELECTED;
			arm->act_bone = NULL;
		}
		
		// TODO: select and activate corresponding vgroup?
		
		/* tag necessary depsgraph updates 
		 * (see rna_Bone_select_update() in rna_armature.c for details)
		 */
		if (arm->flag & ARM_HAS_VIZ_DEPS) {
			DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
		}
		
		/* send necessary notifiers */
		WM_main_add_notifier(NC_GEOM | ND_DATA, ob);
	}
}
Пример #3
0
static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
{
	Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
	bArmature *arm = ob->data;
	Bone *curbone, *pabone, *chbone;
	int direction = RNA_enum_get(op->ptr, "direction");
	const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
	bool found = false;
	
	CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
	{
		curbone = pchan->bone;
		
		if ((curbone->flag & BONE_UNSELECTABLE) == 0) {
			if (curbone == arm->act_bone) {
				if (direction == BONE_SELECT_PARENT) {
					if (pchan->parent == NULL) continue;
					else pabone = pchan->parent->bone;
					
					if (PBONE_SELECTABLE(arm, pabone)) {
						if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
						pabone->flag |= BONE_SELECTED;
						arm->act_bone = pabone;
						
						found = 1;
						break;
					}
				}
				else { /* direction == BONE_SELECT_CHILD */
					/* the child member is only assigned to connected bones, see [#30340] */
#if 0
					if (pchan->child == NULL) continue;
					else chbone = pchan->child->bone;
#else
					/* instead. find _any_ visible child bone, using the first one is a little arbitrary  - campbell */
					chbone = pchan->child ? pchan->child->bone : NULL;
					if (chbone == NULL) {
						bPoseChannel *pchan_child;

						for (pchan_child = ob->pose->chanbase.first; pchan_child; pchan_child = pchan_child->next) {
							/* possible we have multiple children, some invisible */
							if (PBONE_SELECTABLE(arm, pchan_child->bone)) {
								if (pchan_child->parent == pchan) {
									chbone = pchan_child->bone;
									break;
								}
							}
						}
					}

					if (chbone == NULL) continue;
#endif
					
					if (PBONE_SELECTABLE(arm, chbone)) {
						if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
						chbone->flag |= BONE_SELECTED;
						arm->act_bone = chbone;
						
						found = 1;
						break;
					}
				}
			}
		}
	}