Beispiel #1
0
static wmKeyMapItem *wm_keymap_item_find(
        const bContext *C, const char *opname, int opcontext,
        IDProperty *properties, const short hotkey, const bool strict, wmKeyMap **keymap_r)
{
	wmKeyMapItem *found = wm_keymap_item_find_props(C, opname, opcontext, properties, strict, hotkey, keymap_r);

	if (!found && properties) {
		wmOperatorType *ot = WM_operatortype_find(opname, TRUE);
		if (ot) {
			/* make a copy of the properties and set any unset props
			 * to their default values, so the ID property compare function succeeds */
			PointerRNA opptr;
			IDProperty *properties_default = IDP_CopyProperty(properties);

			RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);

			if (WM_operator_properties_default(&opptr, true) ||
			    (!strict && ot->prop && RNA_property_is_set(&opptr, ot->prop)))
			{
				/* for operator that has enum menu, unset it so it always matches */
				if (!strict && ot->prop) {
					RNA_property_unset(&opptr, ot->prop);
				}

				found = wm_keymap_item_find_props(C, opname, opcontext, properties_default, false, hotkey, keymap_r);
			}

			IDP_FreeProperty(properties_default);
			MEM_freeN(properties_default);
		}
	}

	return found;
}
Beispiel #2
0
static void fcm_python_copy(FModifier *fcm, FModifier *src)
{
	FMod_Python *pymod = (FMod_Python *)fcm->data;
	FMod_Python *opymod = (FMod_Python *)src->data;
	
	pymod->prop = IDP_CopyProperty(opymod->prop);
}
Beispiel #3
0
/* used everywhere in blenkernel and text.c */
void *copy_libblock(void *rt)
{
	ID *idn, *id;
	ListBase *lb;
	char *cp, *cpn;
	int idn_len;
	
	id= rt;

	lb= wich_libbase(G.main, GS(id->name));
	idn= alloc_libblock(lb, GS(id->name), id->name+2);
	
	if(idn==NULL) {
		printf("ERROR: Illegal ID name for %s (Crashing now)\n", id->name);
	}
	
	idn_len= MEM_allocN_len(idn);
	if(idn_len - sizeof(ID) > 0) {
		cp= (char *)id;
		cpn= (char *)idn;
		memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID));
	}
	
	id->newid= idn;
	idn->flag |= LIB_NEW;
	if (id->properties) idn->properties = IDP_CopyProperty(id->properties);
	
	/* the duplicate should get a copy of the animdata */
	id_copy_animdata(idn);
	
	return idn;
}
Beispiel #4
0
/* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */
static void poselib_backup_posecopy (tPoseLib_PreviewData *pld)
{
	bActionGroup *agrp;
	bPoseChannel *pchan;
	
	/* for each posechannel that has an actionchannel in */
	for (agrp= pld->act->groups.first; agrp; agrp= agrp->next) {
		/* try to find posechannel */
		pchan= get_pose_channel(pld->pose, agrp->name);
		
		/* backup data if available */
		if (pchan) {
			tPoseLib_Backup *plb;
			
			/* store backup */
			plb= MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup");
			
			plb->pchan= pchan;
			memcpy(&plb->olddata, plb->pchan, sizeof(bPoseChannel));
			
			if (pchan->prop)
				plb->oldprops= IDP_CopyProperty(pchan->prop);
			
			BLI_addtail(&pld->backups, plb);
			
			/* mark as being affected */
			if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))
				pld->selcount++;
			pld->totcount++;
		}
	}
}
Beispiel #5
0
void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb)
{
  BLI_assert(dimb != simb);
  if (simb->metadata) {
    IMB_metadata_free(dimb->metadata);
    dimb->metadata = IDP_CopyProperty(simb->metadata);
  }
}
Beispiel #6
0
/* material nodes use this since they are not treated as libdata */
void copy_libblock_data(ID *id, const ID *id_from, const short do_action)
{
	if (id_from->properties)
		id->properties = IDP_CopyProperty(id_from->properties);

	/* the duplicate should get a copy of the animdata */
	id_copy_animdata(id, do_action);
}
Beispiel #7
0
void WM_keymap_restore_item_to_default(bContext *C, wmKeyMap *keymap, wmKeyMapItem *kmi)
{
	wmWindowManager *wm = CTX_wm_manager(C);
	wmKeyMap *defaultmap, *addonmap;
	wmKeyMapItem *orig;

	if(!keymap)
		return;

	/* construct default keymap from preset + addons */
	defaultmap= wm_keymap_preset(wm, keymap);
	addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);

	if(addonmap) {
		defaultmap = wm_keymap_copy(defaultmap);
		wm_keymap_addon_add(defaultmap, addonmap);
	}

	/* find original item */
	orig = WM_keymap_item_find_id(defaultmap, kmi->id);

	if(orig) {
		/* restore to original */
		if(strcmp(orig->idname, kmi->idname) != 0) {
			BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
			WM_keymap_properties_reset(kmi, NULL);
		}

		if (orig->properties) {
			if(kmi->properties) {
				IDP_FreeProperty(kmi->properties);
				MEM_freeN(kmi->properties);
				kmi->properties= NULL;
			}

			kmi->properties= IDP_CopyProperty(orig->properties);
			kmi->ptr->data= kmi->properties;
		}

		kmi->propvalue = orig->propvalue;
		kmi->type = orig->type;
		kmi->val = orig->val;
		kmi->shift = orig->shift;
		kmi->ctrl = orig->ctrl;
		kmi->alt = orig->alt;
		kmi->oskey = orig->oskey;
		kmi->keymodifier = orig->keymodifier;
		kmi->maptype = orig->maptype;

		WM_keyconfig_update_tag(keymap, kmi);
	}

	/* free temporary keymap */
	if(addonmap) {
		WM_keymap_free(defaultmap);
		MEM_freeN(defaultmap);
	}
}
Beispiel #8
0
/* helper for poseAnim_mapping_get() -> get the relevant F-Curves per PoseChannel */
static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *act, bPoseChannel *pchan)
{
	ListBase curves = {NULL, NULL};
	int transFlags = action_get_item_transforms(act, ob, pchan, &curves);
	
	pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
	
	/* check if any transforms found... */
	if (transFlags) {
		/* make new linkage data */
		tPChanFCurveLink *pfl = MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink");
		PointerRNA ptr;
		
		pfl->fcurves = curves;
		pfl->pchan = pchan;
		
		/* get the RNA path to this pchan - this needs to be freed! */
		RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan, &ptr);
		pfl->pchan_path = RNA_path_from_ID_to_struct(&ptr);
		
		/* add linkage data to operator data */
		BLI_addtail(pfLinks, pfl);
		
		/* set pchan's transform flags */
		if (transFlags & ACT_TRANS_LOC)
			pchan->flag |= POSE_LOC;
		if (transFlags & ACT_TRANS_ROT)
			pchan->flag |= POSE_ROT;
		if (transFlags & ACT_TRANS_SCALE)
			pchan->flag |= POSE_SIZE;
		if (transFlags & ACT_TRANS_BBONE)
			pchan->flag |= POSE_BBONE_SHAPE;
			
		/* store current transforms */
		copy_v3_v3(pfl->oldloc, pchan->loc);
		copy_v3_v3(pfl->oldrot, pchan->eul);
		copy_v3_v3(pfl->oldscale, pchan->size);
		copy_qt_qt(pfl->oldquat, pchan->quat);
		copy_v3_v3(pfl->oldaxis, pchan->rotAxis);
		pfl->oldangle = pchan->rotAngle;
		
		/* store current bbone values */
		pfl->roll1 = pchan->roll1;
		pfl->roll2 = pchan->roll2;
		pfl->curveInX = pchan->curveInX;
		pfl->curveInY = pchan->curveInY;
		pfl->curveOutX = pchan->curveOutX;
		pfl->curveOutY = pchan->curveOutY;
		pfl->ease1 = pchan->ease1;
		pfl->ease2 = pchan->ease2;
		pfl->scaleIn = pchan->scaleIn;
		pfl->scaleOut = pchan->scaleOut;
		
		/* make copy of custom properties */
		if (pchan->prop && (transFlags & ACT_TRANS_PROP))
			pfl->oldprops = IDP_CopyProperty(pchan->prop);
	}
} 
static void node_copy_script(bNode *orig_node, bNode *new_node)
{
    NodeShaderScript *orig_nss = orig_node->storage;
    NodeShaderScript *new_nss = MEM_dupallocN(orig_nss);

    if (orig_nss->bytecode)
        new_nss->bytecode = MEM_dupallocN(orig_nss->bytecode);

    if (orig_nss->prop)
        new_nss->prop = IDP_CopyProperty(orig_nss->prop);

    new_node->storage = new_nss;
}
Beispiel #10
0
/**
 * Allocate a new pose on the heap, and copy the src pose and it's channels
 * into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL.
 *
 * \param dst  Should be freed already, makes entire duplicate.
 */
void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints)
{
	bPose *outPose;
	bPoseChannel *pchan;
	ListBase listb;

	if (!src) {
		*dst = NULL;
		return;
	}
	
	outPose = MEM_callocN(sizeof(bPose), "pose");
	
	BLI_duplicatelist(&outPose->chanbase, &src->chanbase);

	outPose->iksolver = src->iksolver;
	outPose->ikdata = NULL;
	outPose->ikparam = MEM_dupallocN(src->ikparam);
	outPose->avs = src->avs;
	
	for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {

		if (pchan->custom) {
			id_us_plus(&pchan->custom->id);
		}

		/* warning, O(n2) here, but it's a rarely used feature. */
		if (pchan->custom_tx) {
			pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name);
		}

		if (copy_constraints) {
			BKE_constraints_copy(&listb, &pchan->constraints, true);  // BKE_constraints_copy NULLs listb
			pchan->constraints = listb;
			pchan->mpath = NULL; /* motion paths should not get copied yet... */
		}
		
		if (pchan->prop) {
			pchan->prop = IDP_CopyProperty(pchan->prop);
		}
	}

	/* for now, duplicate Bone Groups too when doing this */
	if (copy_constraints) {
		BLI_duplicatelist(&outPose->agroups, &src->agroups);
	}
	
	*dst = outPose;
}
Beispiel #11
0
/**
 * Copy the internal members of each pose channel including constraints
 * and ID-Props, used when duplicating bones in editmode.
 * (unlike copy_pose_channel_data which only does posing-related stuff).
 *
 * \note use when copying bones in editmode (on returned value from #BKE_pose_channel_verify)
 */
void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_from)
{
	/* copy transform locks */
	pchan->protectflag = pchan_from->protectflag;

	/* copy rotation mode */
	pchan->rotmode = pchan_from->rotmode;

	/* copy bone group */
	pchan->agrp_index = pchan_from->agrp_index;

	/* ik (dof) settings */
	pchan->ikflag = pchan_from->ikflag;
	copy_v3_v3(pchan->limitmin, pchan_from->limitmin);
	copy_v3_v3(pchan->limitmax, pchan_from->limitmax);
	copy_v3_v3(pchan->stiffness, pchan_from->stiffness);
	pchan->ikstretch = pchan_from->ikstretch;
	pchan->ikrotweight = pchan_from->ikrotweight;
	pchan->iklinweight = pchan_from->iklinweight;
	
	/* bbone settings (typically not animated) */
	pchan->bboneflag = pchan_from->bboneflag;
	pchan->bbone_next = pchan_from->bbone_next;
	pchan->bbone_prev = pchan_from->bbone_prev;

	/* constraints */
	BKE_constraints_copy(&pchan->constraints, &pchan_from->constraints, true);

	/* id-properties */
	if (pchan->prop) {
		/* unlikely but possible it exists */
		IDP_FreeProperty(pchan->prop);
		MEM_freeN(pchan->prop);
		pchan->prop = NULL;
	}
	if (pchan_from->prop) {
		pchan->prop = IDP_CopyProperty(pchan_from->prop);
	}

	/* custom shape */
	pchan->custom = pchan_from->custom;
	if (pchan->custom) {
		id_us_plus(&pchan->custom->id);
	}

	pchan->custom_scale = pchan_from->custom_scale;
}
Beispiel #12
0
static wmKeyMapItem *wm_keymap_item_copy(wmKeyMapItem *kmi)
{
	wmKeyMapItem *kmin = MEM_dupallocN(kmi);

	kmin->prev= kmin->next= NULL;
	kmin->flag &= ~KMI_UPDATE;

	if(kmin->properties) {
		kmin->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr");
		WM_operator_properties_create(kmin->ptr, kmin->idname);

		kmin->properties= IDP_CopyProperty(kmin->properties);
		kmin->ptr->data= kmin->properties;
	}

	return kmin;
}
Beispiel #13
0
/* dst should be freed already, makes entire duplicate */
void copy_pose (bPose **dst, bPose *src, int copycon)
{
	bPose *outPose;
	bPoseChannel *pchan;
	ListBase listb;
	
	if (!src) {
		*dst=NULL;
		return;
	}
	
	if (*dst==src) {
		printf("copy_pose source and target are the same\n");
		*dst=NULL;
		return;
	}
	
	outPose= MEM_callocN(sizeof(bPose), "pose");
	
	BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
	
	outPose->iksolver = src->iksolver;
	outPose->ikdata = NULL;
	outPose->ikparam = MEM_dupallocN(src->ikparam);
	
	for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
		// TODO: rename this argument...
		if (copycon) {
			copy_constraints(&listb, &pchan->constraints, TRUE);  // copy_constraints NULLs listb
			pchan->constraints= listb;
			pchan->path= NULL; // XXX remove this line when the new motionpaths are ready... (depreceated code)
			pchan->mpath= NULL; /* motion paths should not get copied yet... */
		}
		
		if(pchan->prop) {
			pchan->prop= IDP_CopyProperty(pchan->prop);
		}
	}

	/* for now, duplicate Bone Groups too when doing this */
	if (copycon)
		BLI_duplicatelist(&outPose->agroups, &src->agroups);
	
	*dst=outPose;
}
EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones,
                                   Object *src_ob, Object *dst_ob)
{
	EditBone *eBone = MEM_mallocN(sizeof(EditBone), "addup_editbone");
	
	/*	Copy data from old bone to new bone */
	memcpy(eBone, curBone, sizeof(EditBone));
	
	curBone->temp.ebone = eBone;
	eBone->temp.ebone = curBone;
	
	if (name != NULL) {
		BLI_strncpy(eBone->name, name, sizeof(eBone->name));
	}

	unique_editbone_name(editbones, eBone->name, NULL);
	BLI_addtail(editbones, eBone);
	
	/* copy the ID property */
	if (curBone->prop)
		eBone->prop = IDP_CopyProperty(curBone->prop);

	/* Lets duplicate the list of constraints that the
	 * current bone has.
	 */
	if (src_ob->pose) {
		bPoseChannel *chanold, *channew;
		
		chanold = BKE_pose_channel_verify(src_ob->pose, curBone->name);
		if (chanold) {
			/* WARNING: this creates a new posechannel, but there will not be an attached bone
			 *		yet as the new bones created here are still 'EditBones' not 'Bones'.
			 */
			channew = BKE_pose_channel_verify(dst_ob->pose, eBone->name);

			if (channew) {
				BKE_pose_channel_copy_data(channew, chanold);
			}
		}
	}
	
	return eBone;
}
Beispiel #15
0
/* dst should be freed already, makes entire duplicate */
void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon)
{
	bPose *outPose;
	bPoseChannel *pchan;
	ListBase listb;

	if (!src) {
		*dst = NULL;
		return;
	}
	
	outPose = MEM_callocN(sizeof(bPose), "pose");
	
	BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
	
	outPose->iksolver = src->iksolver;
	outPose->ikdata = NULL;
	outPose->ikparam = MEM_dupallocN(src->ikparam);
	outPose->avs = src->avs;
	
	for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
		/* TODO: rename this argument... */
		if (copycon) {
			BKE_copy_constraints(&listb, &pchan->constraints, TRUE);  // BKE_copy_constraints NULLs listb
			pchan->constraints = listb;
			pchan->mpath = NULL; /* motion paths should not get copied yet... */
		}
		
		if (pchan->prop) {
			pchan->prop = IDP_CopyProperty(pchan->prop);
		}
	}

	/* for now, duplicate Bone Groups too when doing this */
	if (copycon)
		BLI_duplicatelist(&outPose->agroups, &src->agroups);
	
	*dst = outPose;
}
Beispiel #16
0
void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src)
{
	EditBone *ebone_src;
	EditBone *ebone_dst;

	BLI_assert(BLI_listbase_is_empty(lb_dst));

	for (ebone_src = lb_src->first; ebone_src; ebone_src = ebone_src->next) {
		ebone_dst = MEM_dupallocN(ebone_src);
		if (ebone_dst->prop) {
			ebone_dst->prop = IDP_CopyProperty(ebone_dst->prop);
		}
		ebone_src->temp.ebone = ebone_dst;
		BLI_addtail(lb_dst, ebone_dst);
	}

	/* set pointers */
	for (ebone_dst = lb_dst->first; ebone_dst; ebone_dst = ebone_dst->next) {
		if (ebone_dst->parent) {
			ebone_dst->parent = ebone_dst->parent->temp.ebone;
		}
	}
}
Beispiel #17
0
/* makes copies of internal data, unlike copy_pose_channel_data which only
 * copies the pose state.
 * hint: use when copying bones in editmode (on returned value from verify_pose_channel) */
void duplicate_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *pchan_from)
{
	/* copy transform locks */
	pchan->protectflag = pchan_from->protectflag;

	/* copy rotation mode */
	pchan->rotmode = pchan_from->rotmode;

	/* copy bone group */
	pchan->agrp_index= pchan_from->agrp_index;

	/* ik (dof) settings */
	pchan->ikflag = pchan_from->ikflag;
	VECCOPY(pchan->limitmin, pchan_from->limitmin);
	VECCOPY(pchan->limitmax, pchan_from->limitmax);
	VECCOPY(pchan->stiffness, pchan_from->stiffness);
	pchan->ikstretch= pchan_from->ikstretch;
	pchan->ikrotweight= pchan_from->ikrotweight;
	pchan->iklinweight= pchan_from->iklinweight;

	/* constraints */
	copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);

	/* id-properties */
	if(pchan->prop) {
		/* unlikely but possible it exists */
		IDP_FreeProperty(pchan->prop);
		MEM_freeN(pchan->prop);
		pchan->prop= NULL;
	}
	if(pchan_from->prop) {
		pchan->prop= IDP_CopyProperty(pchan_from->prop);
	}

	/* custom shape */
	pchan->custom= pchan_from->custom;
}
Beispiel #18
0
/* put EditMode back in Object */
void ED_armature_from_edit(bArmature *arm)
{
	EditBone *eBone, *neBone;
	Bone *newBone;
	Object *obt;
	
	/* armature bones */
	BKE_armature_bonelist_free(&arm->bonebase);
	arm->act_bone = NULL;
	
	/* remove zero sized bones, this gives unstable restposes */
	for (eBone = arm->edbo->first; eBone; eBone = neBone) {
		float len = len_v3v3(eBone->head, eBone->tail);
		neBone = eBone->next;
		if (len <= 0.000001f) {  /* FLT_EPSILON is too large? */
			EditBone *fBone;
			
			/*	Find any bones that refer to this bone	*/
			for (fBone = arm->edbo->first; fBone; fBone = fBone->next) {
				if (fBone->parent == eBone)
					fBone->parent = eBone->parent;
			}
			if (G.debug & G_DEBUG)
				printf("Warning: removed zero sized bone: %s\n", eBone->name);
			bone_free(arm, eBone);
		}
	}
	
	/*	Copy the bones from the editData into the armature */
	for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
		newBone = MEM_callocN(sizeof(Bone), "bone");
		eBone->temp.bone = newBone;   /* Associate the real Bones with the EditBones */
		
		BLI_strncpy(newBone->name, eBone->name, sizeof(newBone->name));
		copy_v3_v3(newBone->arm_head, eBone->head);
		copy_v3_v3(newBone->arm_tail, eBone->tail);
		newBone->arm_roll = eBone->roll;
		
		newBone->flag = eBone->flag;
		
		if (eBone == arm->act_edbone) {
			/* don't change active selection, this messes up separate which uses
			 * editmode toggle and can separate active bone which is de-selected originally */
			/* newBone->flag |= BONE_SELECTED; */ /* important, editbones can be active with only 1 point selected */
			arm->act_bone = newBone;
		}
		newBone->roll = 0.0f;
		
		newBone->weight = eBone->weight;
		newBone->dist = eBone->dist;
		
		newBone->xwidth = eBone->xwidth;
		newBone->zwidth = eBone->zwidth;
		newBone->ease1 = eBone->ease1;
		newBone->ease2 = eBone->ease2;
		newBone->rad_head = eBone->rad_head;
		newBone->rad_tail = eBone->rad_tail;
		newBone->segments = eBone->segments;
		newBone->layer = eBone->layer;
		
		if (eBone->prop)
			newBone->prop = IDP_CopyProperty(eBone->prop);
	}
	
	/* Fix parenting in a separate pass to ensure ebone->bone connections
	 * are valid at this point */
	for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
		newBone = eBone->temp.bone;
		if (eBone->parent) {
			newBone->parent = eBone->parent->temp.bone;
			BLI_addtail(&newBone->parent->childbase, newBone);
			
			{
				float M_parentRest[3][3];
				float iM_parentRest[3][3];
				
				/* Get the parent's  matrix (rotation only) */
				ED_armature_ebone_to_mat3(eBone->parent, M_parentRest);
				
				/* Invert the parent matrix */
				invert_m3_m3(iM_parentRest, M_parentRest);
				
				/* Get the new head and tail */
				sub_v3_v3v3(newBone->head, eBone->head, eBone->parent->tail);
				sub_v3_v3v3(newBone->tail, eBone->tail, eBone->parent->tail);
				
				mul_m3_v3(iM_parentRest, newBone->head);
				mul_m3_v3(iM_parentRest, newBone->tail);
			}
		}
		/*	...otherwise add this bone to the armature's bonebase */
		else {
			copy_v3_v3(newBone->head, eBone->head);
			copy_v3_v3(newBone->tail, eBone->tail);
			BLI_addtail(&arm->bonebase, newBone);
		}
	}
	
	/* Make a pass through the new armature to fix rolling */
	/* also builds restposition again (like BKE_armature_where_is) */
	fix_bonelist_roll(&arm->bonebase, arm->edbo);
	
	/* so all users of this armature should get rebuilt */
	for (obt = G.main->object.first; obt; obt = obt->id.next) {
		if (obt->data == arm)
			BKE_pose_rebuild(obt, arm);
	}
	
	DAG_id_tag_update(&arm->id, 0);
}
/** 
 * Move here pose function for game engine so that we can mix with GE objects
 * Principle is as follow:
 * Use Blender structures so that BKE_pose_where_is can be used unchanged
 * Copy the constraint so that they can be enabled/disabled/added/removed at runtime
 * Don't copy the constraints for the pose used by the Action actuator, it does not need them.
 * Scan the constraint structures so that the KX equivalent of target objects are identified and 
 * stored in separate list.
 * When it is about to evaluate the pose, set the KX object position in the obmat of the corresponding
 * Blender objects and restore after the evaluation.
 */
static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
{
	bPose *out;
	bPoseChannel *pchan, *outpchan;
	GHash *ghash;
	
	/* the game engine copies the current armature pose and then swaps
	 * the object pose pointer. this makes it possible to change poses
	 * without affecting the original blender data. */

	if (!src) {
		*dst=NULL;
		return;
	}
	else if (*dst==src) {
		printf("game_copy_pose source and target are the same\n");
		*dst=NULL;
		return;
	}
	
	out= (bPose*)MEM_dupallocN(src);
	out->chanhash = NULL;
	out->agroups.first= out->agroups.last= NULL;
	out->ikdata = NULL;
	out->ikparam = MEM_dupallocN(src->ikparam);
	out->flag |= POSE_GAME_ENGINE;
	BLI_duplicatelist(&out->chanbase, &src->chanbase);

	/* remap pointers */
	ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "game_copy_pose gh");

	pchan= (bPoseChannel *)src->chanbase.first;
	outpchan= (bPoseChannel *)out->chanbase.first;
	for (; pchan; pchan=pchan->next, outpchan=outpchan->next)
		BLI_ghash_insert(ghash, pchan, outpchan);

	for (pchan = (bPoseChannel *)out->chanbase.first; pchan; pchan = pchan->next) {
		pchan->parent= (bPoseChannel *)BLI_ghash_lookup(ghash, pchan->parent);
		pchan->child= (bPoseChannel *)BLI_ghash_lookup(ghash, pchan->child);

		if (copy_constraint) {
			ListBase listb;
			// copy all constraint for backward compatibility
			// BKE_constraints_copy NULLs listb, no need to make extern for this operation.
			BKE_constraints_copy(&listb, &pchan->constraints, false);
			pchan->constraints= listb;
		}
		else {
			BLI_listbase_clear(&pchan->constraints);
		}

		if (pchan->custom) {
			id_us_plus(&pchan->custom->id);
		}

		// fails to link, props are not used in the BGE yet.
#if 0
		if (pchan->prop)
			pchan->prop= IDP_CopyProperty(pchan->prop);
#endif
		pchan->prop= NULL;
	}

	BLI_ghash_free(ghash, NULL, NULL);
	// set acceleration structure for channel lookup
	BKE_pose_channels_hash_make(out);
	*dst=out;
}
Beispiel #20
0
Scene *BKE_scene_copy(Scene *sce, int type)
{
	Scene *scen;
	ToolSettings *ts;
	Base *base, *obase;
	
	if (type == SCE_COPY_EMPTY) {
		ListBase lb;
		/* XXX. main should become an arg */
		scen = BKE_scene_add(G.main, sce->id.name + 2);
		
		lb = scen->r.layers;
		scen->r = sce->r;
		scen->r.layers = lb;
		scen->unit = sce->unit;
		scen->physics_settings = sce->physics_settings;
		scen->gm = sce->gm;
		scen->audio = sce->audio;

		MEM_freeN(scen->toolsettings);
	}
	else {
		scen = BKE_libblock_copy(&sce->id);
		BLI_duplicatelist(&(scen->base), &(sce->base));
		
		clear_id_newpoins();
		
		id_us_plus((ID *)scen->world);
		id_us_plus((ID *)scen->set);
		id_us_plus((ID *)scen->gm.dome.warptext);

		scen->ed = NULL;
		scen->theDag = NULL;
		scen->obedit = NULL;
		scen->stats = NULL;
		scen->fps_info = NULL;

		BLI_duplicatelist(&(scen->markers), &(sce->markers));
		BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
		BLI_duplicatelist(&(scen->r.layers), &(sce->r.layers));
		BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));

		if (sce->nodetree) {
			/* ID's are managed on both copy and switch */
			scen->nodetree = ntreeCopyTree(sce->nodetree);
			ntreeSwitchID(scen->nodetree, &sce->id, &scen->id);
		}

		obase = sce->base.first;
		base = scen->base.first;
		while (base) {
			id_us_plus(&base->object->id);
			if (obase == sce->basact) scen->basact = base;
	
			obase = obase->next;
			base = base->next;
		}

		/* copy color management settings */
		BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings);
		BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings);
		BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings);

		BLI_strncpy(scen->sequencer_colorspace_settings.name, sce->sequencer_colorspace_settings.name,
		            sizeof(scen->sequencer_colorspace_settings.name));

		/* remove animation used by sequencer */
		if (type != SCE_COPY_FULL)
			remove_sequencer_fcurves(scen);
	}

	/* tool settings */
	scen->toolsettings = MEM_dupallocN(sce->toolsettings);

	ts = scen->toolsettings;
	if (ts) {
		if (ts->vpaint) {
			ts->vpaint = MEM_dupallocN(ts->vpaint);
			ts->vpaint->paintcursor = NULL;
			ts->vpaint->vpaint_prev = NULL;
			ts->vpaint->wpaint_prev = NULL;
			BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint);
		}
		if (ts->wpaint) {
			ts->wpaint = MEM_dupallocN(ts->wpaint);
			ts->wpaint->paintcursor = NULL;
			ts->wpaint->vpaint_prev = NULL;
			ts->wpaint->wpaint_prev = NULL;
			BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint);
		}
		if (ts->sculpt) {
			ts->sculpt = MEM_dupallocN(ts->sculpt);
			BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint);
		}

		BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint);
		ts->imapaint.paintcursor = NULL;
		ts->particle.paintcursor = NULL;
	}
	
	/* make a private copy of the avicodecdata */
	if (sce->r.avicodecdata) {
		scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
		scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
		scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
	}
	
	/* make a private copy of the qtcodecdata */
	if (sce->r.qtcodecdata) {
		scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
		scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
	}
	
	if (sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */
		scen->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
	}

	/* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
	 * are done outside of blenkernel with ED_objects_single_users! */

	/*  camera */
	if (type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
		ID_NEW(scen->camera);
	}
	
	/* before scene copy */
	sound_create_scene(scen);

	/* world */
	if (type == SCE_COPY_FULL) {
		BKE_copy_animdata_id_action((ID *)scen);
		if (scen->world) {
			id_us_plus((ID *)scen->world);
			scen->world = BKE_world_copy(scen->world);
			BKE_copy_animdata_id_action((ID *)scen->world);
		}

		if (sce->ed) {
			scen->ed = MEM_callocN(sizeof(Editing), "addseq");
			scen->ed->seqbasep = &scen->ed->seqbase;
			BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
		}
	}

	return scen;
}
Beispiel #21
0
/* converts Bones to EditBone list, used for tools as well */
EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone)
{
	EditBone    *eBone;
	EditBone    *eBoneAct = NULL;
	EditBone    *eBoneTest = NULL;
	Bone        *curBone;
		
	for (curBone = bones->first; curBone; curBone = curBone->next) {
		eBone = MEM_callocN(sizeof(EditBone), "make_editbone");
		
		/*	Copy relevant data from bone to eBone */
		eBone->parent = parent;
		BLI_strncpy(eBone->name, curBone->name, sizeof(eBone->name));
		eBone->flag = curBone->flag;
		
		/* fix selection flags */
		if (eBone->flag & BONE_SELECTED) {
			/* if the bone is selected the copy its root selection to the parents tip */
			eBone->flag |= BONE_TIPSEL;
			if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
				eBone->parent->flag |= BONE_TIPSEL;
				eBone->flag &= ~BONE_ROOTSEL; /* this is ignored when there is a connected parent, so unset it */
			}
			else {
				eBone->flag |= BONE_ROOTSEL;
			}
		}
		else {
			/* if the bone is not selected, but connected to its parent
			 * always use the parents tip selection state */
			if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
				eBone->flag &= ~BONE_ROOTSEL;
			}
		}
		
		copy_v3_v3(eBone->head, curBone->arm_head);
		copy_v3_v3(eBone->tail, curBone->arm_tail);
		eBone->roll = curBone->arm_roll;
		
		/* rest of stuff copy */
		eBone->length = curBone->length;
		eBone->dist = curBone->dist;
		eBone->weight = curBone->weight;
		eBone->xwidth = curBone->xwidth;
		eBone->zwidth = curBone->zwidth;
		eBone->ease1 = curBone->ease1;
		eBone->ease2 = curBone->ease2;
		eBone->rad_head = curBone->rad_head;
		eBone->rad_tail = curBone->rad_tail;
		eBone->segments = curBone->segments;
		eBone->layer = curBone->layer;
		
		if (curBone->prop)
			eBone->prop = IDP_CopyProperty(curBone->prop);
		
		BLI_addtail(edbo, eBone);
		
		/*	Add children if necessary */
		if (curBone->childbase.first) {
			eBoneTest = make_boneList(edbo, &curBone->childbase, eBone, actBone);
			if (eBoneTest)
				eBoneAct = eBoneTest;
		}
		
		if (curBone == actBone)
			eBoneAct = eBone;
	}
	
	return eBoneAct;
}
Beispiel #22
0
/* converts Bones to EditBone list, used for tools as well */
EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone)
{
	EditBone    *eBone;
	EditBone    *eBoneAct = NULL;
	EditBone    *eBoneTest = NULL;
	Bone        *curBone;
		
	for (curBone = bones->first; curBone; curBone = curBone->next) {
		eBone = MEM_callocN(sizeof(EditBone), "make_editbone");
		
		/* Copy relevant data from bone to eBone
		 * Keep selection logic in sync with ED_armature_sync_selection.
		 */
		eBone->parent = parent;
		BLI_strncpy(eBone->name, curBone->name, sizeof(eBone->name));
		eBone->flag = curBone->flag;
		
		/* fix selection flags */
		if (eBone->flag & BONE_SELECTED) {
			/* if the bone is selected the copy its root selection to the parents tip */
			eBone->flag |= BONE_TIPSEL;
			if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
				eBone->parent->flag |= BONE_TIPSEL;
			}

			/* For connected bones, take care when changing the selection when we have a connected parent,
			 * this flag is a copy of '(eBone->parent->flag & BONE_TIPSEL)'. */
			eBone->flag |= BONE_ROOTSEL;
		}
		else {
			/* if the bone is not selected, but connected to its parent
			 * always use the parents tip selection state */
			if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
				eBone->flag &= ~BONE_ROOTSEL;
			}
		}
		
		copy_v3_v3(eBone->head, curBone->arm_head);
		copy_v3_v3(eBone->tail, curBone->arm_tail);
		eBone->roll = curBone->arm_roll;
		
		/* rest of stuff copy */
		eBone->length = curBone->length;
		eBone->dist = curBone->dist;
		eBone->weight = curBone->weight;
		eBone->xwidth = curBone->xwidth;
		eBone->zwidth = curBone->zwidth;
		eBone->rad_head = curBone->rad_head;
		eBone->rad_tail = curBone->rad_tail;
		eBone->segments = curBone->segments;
		eBone->layer = curBone->layer;

		/* Bendy-Bone parameters */
		eBone->roll1 = curBone->roll1;
		eBone->roll2 = curBone->roll2;
		eBone->curveInX = curBone->curveInX;
		eBone->curveInY = curBone->curveInY;
		eBone->curveOutX = curBone->curveOutX;
		eBone->curveOutY = curBone->curveOutY;
		eBone->ease1 = curBone->ease1;
		eBone->ease2 = curBone->ease2;
		eBone->scaleIn = curBone->scaleIn;
		eBone->scaleOut = curBone->scaleOut;

		if (curBone->prop)
			eBone->prop = IDP_CopyProperty(curBone->prop);
		
		BLI_addtail(edbo, eBone);
		
		/*	Add children if necessary */
		if (curBone->childbase.first) {
			eBoneTest = make_boneList(edbo, &curBone->childbase, eBone, actBone);
			if (eBoneTest)
				eBoneAct = eBoneTest;
		}
		
		if (curBone == actBone)
			eBoneAct = eBone;
	}
	
	return eBoneAct;
}
Beispiel #23
0
/**
 * Allocate a new pose on the heap, and copy the src pose and it's channels
 * into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL.
 *
 * \param dst  Should be freed already, makes entire duplicate.
 */
void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints)
{
	bPose *outPose;
	bPoseChannel *pchan;
	ListBase listb;

	if (!src) {
		*dst = NULL;
		return;
	}
	
	outPose = MEM_callocN(sizeof(bPose), "pose");
	
	BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
	
	/* Rebuild ghash here too, so that name lookups below won't be too bad...
	 * BUT this will have the penalty that the ghash will be built twice
	 * if BKE_pose_rebuild() gets called after this...
	 */
	if (outPose->chanbase.first != outPose->chanbase.last) {
		outPose->chanhash = NULL;
		BKE_pose_channels_hash_make(outPose);
	}
	
	outPose->iksolver = src->iksolver;
	outPose->ikdata = NULL;
	outPose->ikparam = MEM_dupallocN(src->ikparam);
	outPose->avs = src->avs;
	
	for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {

		if (pchan->custom) {
			id_us_plus(&pchan->custom->id);
		}

		/* warning, O(n2) here, if done without the hash, but these are rarely used features. */
		if (pchan->custom_tx) {
			pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name);
		}
		if (pchan->bbone_prev) {
			pchan->bbone_prev = BKE_pose_channel_find_name(outPose, pchan->bbone_prev->name);
		}
		if (pchan->bbone_next) {
			pchan->bbone_next = BKE_pose_channel_find_name(outPose, pchan->bbone_next->name);
		}

		if (copy_constraints) {
			BKE_constraints_copy(&listb, &pchan->constraints, true);  // BKE_constraints_copy NULLs listb
			pchan->constraints = listb;
			pchan->mpath = NULL; /* motion paths should not get copied yet... */
		}
		
		if (pchan->prop) {
			pchan->prop = IDP_CopyProperty(pchan->prop);
		}
	}

	/* for now, duplicate Bone Groups too when doing this */
	if (copy_constraints) {
		BLI_duplicatelist(&outPose->agroups, &src->agroups);
	}
	
	*dst = outPose;
}
Beispiel #24
0
/* put EditMode back in Object */
void ED_armature_from_edit(bArmature *arm)
{
	EditBone *eBone, *neBone;
	Bone *newBone;
	Object *obt;
	
	/* armature bones */
	BKE_armature_bonelist_free(&arm->bonebase);
	arm->act_bone = NULL;
	
	/* remove zero sized bones, this gives unstable restposes */
	for (eBone = arm->edbo->first; eBone; eBone = neBone) {
		float len_sq = len_squared_v3v3(eBone->head, eBone->tail);
		neBone = eBone->next;
		if (len_sq <= SQUARE(0.000001f)) {  /* FLT_EPSILON is too large? */
			EditBone *fBone;
			
			/* Find any bones that refer to this bone */
			for (fBone = arm->edbo->first; fBone; fBone = fBone->next) {
				if (fBone->parent == eBone)
					fBone->parent = eBone->parent;
			}
			if (G.debug & G_DEBUG)
				printf("Warning: removed zero sized bone: %s\n", eBone->name);
			bone_free(arm, eBone);
		}
	}
	
	/*	Copy the bones from the editData into the armature */
	for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
		newBone = MEM_callocN(sizeof(Bone), "bone");
		eBone->temp.bone = newBone;   /* Associate the real Bones with the EditBones */
		
		BLI_strncpy(newBone->name, eBone->name, sizeof(newBone->name));
		copy_v3_v3(newBone->arm_head, eBone->head);
		copy_v3_v3(newBone->arm_tail, eBone->tail);
		newBone->arm_roll = eBone->roll;
		
		newBone->flag = eBone->flag;
		
		if (eBone == arm->act_edbone) {
			/* don't change active selection, this messes up separate which uses
			 * editmode toggle and can separate active bone which is de-selected originally */
			/* newBone->flag |= BONE_SELECTED; */ /* important, editbones can be active with only 1 point selected */
			arm->act_bone = newBone;
		}
		newBone->roll = 0.0f;
		
		newBone->weight = eBone->weight;
		newBone->dist = eBone->dist;
		
		newBone->xwidth = eBone->xwidth;
		newBone->zwidth = eBone->zwidth;
		newBone->rad_head = eBone->rad_head;
		newBone->rad_tail = eBone->rad_tail;
		newBone->segments = eBone->segments;
		newBone->layer = eBone->layer;

		/* Bendy-Bone parameters */
		newBone->roll1 = eBone->roll1;
		newBone->roll2 = eBone->roll2;
		newBone->curveInX = eBone->curveInX;
		newBone->curveInY = eBone->curveInY;
		newBone->curveOutX = eBone->curveOutX;
		newBone->curveOutY = eBone->curveOutY;
		newBone->ease1 = eBone->ease1;
		newBone->ease2 = eBone->ease2;
		newBone->scaleIn = eBone->scaleIn;
		newBone->scaleOut = eBone->scaleOut;


		if (eBone->prop)
			newBone->prop = IDP_CopyProperty(eBone->prop);
	}
	
	/* Fix parenting in a separate pass to ensure ebone->bone connections are valid at this point.
	 * Do not set bone->head/tail here anymore, using EditBone data for that is not OK since our later fiddling
	 * with parent's arm_mat (for roll conversion) may have some small but visible impact on locations (T46010). */
	for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
		newBone = eBone->temp.bone;
		if (eBone->parent) {
			newBone->parent = eBone->parent->temp.bone;
			BLI_addtail(&newBone->parent->childbase, newBone);
		}
		/*	...otherwise add this bone to the armature's bonebase */
		else {
			BLI_addtail(&arm->bonebase, newBone);
		}
	}
	
	/* Finalize definition of restpose data (roll, bone_mat, arm_mat, head/tail...). */
	armature_finalize_restpose(&arm->bonebase, arm->edbo);
	
	/* so all users of this armature should get rebuilt */
	for (obt = G.main->object.first; obt; obt = obt->id.next) {
		if (obt->data == arm) {
			BKE_pose_rebuild(obt, arm);
		}
	}
	
	DAG_id_tag_update(&arm->id, 0);
}