示例#1
0
文件: action.c 项目: diosney/blender
void BKE_pose_channels_free(bPose *pose) 
{
	bPoseChannel *pchan;
	
	if (pose->chanbase.first) {
		for (pchan = pose->chanbase.first; pchan; pchan = pchan->next)
			BKE_pose_channel_free(pchan);
		
		BLI_freelistN(&pose->chanbase);
	}

	BKE_pose_channels_hash_free(pose);
}
示例#2
0
/* Helper function for armature separating - remove certain bones from the given armature 
 *	sel: remove selected bones from the armature, otherwise the unselected bones are removed
 *  (ob is not in editmode)
 */
static void separate_armature_bones(Object *ob, short sel) 
{
	bArmature *arm = (bArmature *)ob->data;
	bPoseChannel *pchan, *pchann;
	EditBone *curbone;
	
	/* make local set of editbones to manipulate here */
	ED_armature_to_edit(ob);
	
	/* go through pose-channels, checking if a bone should be removed */
	for (pchan = ob->pose->chanbase.first; pchan; pchan = pchann) {
		pchann = pchan->next;
		curbone = editbone_name_exists(arm->edbo, pchan->name);
		
		/* check if bone needs to be removed */
		if ( (sel && (curbone->flag & BONE_SELECTED)) ||
		     (!sel && !(curbone->flag & BONE_SELECTED)) )
		{
			EditBone *ebo;
			bPoseChannel *pchn;
			
			/* clear the bone->parent var of any bone that had this as its parent  */
			for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
				if (ebo->parent == curbone) {
					ebo->parent = NULL;
					ebo->temp = NULL; /* this is needed to prevent random crashes with in ED_armature_from_edit */
					ebo->flag &= ~BONE_CONNECTED;
				}
			}
			
			/* clear the pchan->parent var of any pchan that had this as its parent */
			for (pchn = ob->pose->chanbase.first; pchn; pchn = pchn->next) {
				if (pchn->parent == pchan)
					pchn->parent = NULL;
			}
			
			/* free any of the extra-data this pchan might have */
			BKE_pose_channel_free(pchan);
			BKE_pose_channels_hash_free(ob->pose);
			
			/* get rid of unneeded bone */
			bone_free(arm, curbone);
			BLI_freelinkN(&ob->pose->chanbase, pchan);
		}
	}
	
	/* exit editmode (recalculates pchans too) */
	ED_armature_from_edit(ob);
	ED_armature_edit_free(ob);
}
示例#3
0
文件: action.c 项目: UPBGE/blender
/**
 * Selectively remove pose channels.
 */
void BKE_pose_channels_remove(
        Object *ob,
        bool (*filter_fn)(const char *bone_name, void *user_data), void *user_data)
{
	/* Erase any associated pose channel, along with any references to them */
	if (ob->pose) {
		bPoseChannel *pchan, *pchan_next;
		bConstraint *con;

		for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan_next) {
			pchan_next = pchan->next;

			if (filter_fn(pchan->name, user_data)) {
				/* Bone itself is being removed */
				BKE_pose_channel_free(pchan);
				if (ob->pose->chanhash) {
					BLI_ghash_remove(ob->pose->chanhash, pchan->name, NULL, NULL);
				}
				BLI_freelinkN(&ob->pose->chanbase, pchan);
			}
			else {
				/* Maybe something the bone references is being removed instead? */
				for (con = pchan->constraints.first; con; con = con->next) {
					const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
					ListBase targets = {NULL, NULL};
					bConstraintTarget *ct;

					if (cti && cti->get_constraint_targets) {
						cti->get_constraint_targets(con, &targets);

						for (ct = targets.first; ct; ct = ct->next) {
							if (ct->tar == ob) {
								if (ct->subtarget[0]) {
									if (filter_fn(ct->subtarget, user_data)) {
										con->flag |= CONSTRAINT_DISABLE;
										ct->subtarget[0] = 0;
									}
								}
							}
						}

						if (cti->flush_constraint_targets)
							cti->flush_constraint_targets(con, &targets, 0);
					}
				}
				
				if (pchan->bbone_prev) {
					if (filter_fn(pchan->bbone_prev->name, user_data))
						pchan->bbone_prev = NULL;
				}
				if (pchan->bbone_next) {
					if (filter_fn(pchan->bbone_next->name, user_data))
						pchan->bbone_next = NULL;
				}
				
				if (pchan->custom_tx) {
					if (filter_fn(pchan->custom_tx->name, user_data))
						pchan->custom_tx = NULL;
				}
			}
		}
	}
}