示例#1
0
static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob, int from_mix)
{
	if(object_insert_shape_key(scene, ob, NULL, from_mix)) {
		Key *key= ob_get_key(ob);
		ob->shapenr= BLI_countlist(&key->block);

		WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
	}
}
示例#2
0
文件: rna_key.c 项目: mik0001/Blender
static Key *rna_ShapeKey_find_key(ID *id)
{
	switch(GS(id->name)) {
		case ID_CU: return ((Curve*)id)->key;
		case ID_KE: return (Key*)id;
		case ID_LT: return ((Lattice*)id)->key;
		case ID_ME: return ((Mesh*)id)->key;
		case ID_OB: return ob_get_key((Object*)id);
		default: return NULL;
	}
}
示例#3
0
static void deformVertsEM(ModifierData *md, Object *ob,
						struct EditMesh *UNUSED(editData),
						DerivedMesh *derivedData,
						float (*vertexCos)[3],
						int numVerts)
{
	Key *key= ob_get_key(ob);

	if(key && key->type == KEY_RELATIVE)
		deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
}
示例#4
0
文件: rna_key.c 项目: mik0001/Blender
static void rna_Key_update_data(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
	Key *key= ptr->id.data;
	Object *ob;

	for(ob=bmain->object.first; ob; ob= ob->id.next) {
		if(ob_get_key(ob) == key) {
			DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
			WM_main_add_notifier(NC_OBJECT|ND_MODIFIER, ob);
		}
	}
}
示例#5
0
static int shape_key_move_exec(bContext *C, wmOperator *op)
{
	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;

	int type= RNA_enum_get(op->ptr, "type");
	Key *key= ob_get_key(ob);

	if(key) {
		KeyBlock *kb, *kb_other;
		int shapenr_act= ob->shapenr-1;
		int shapenr_swap= shapenr_act + type;
		kb= BLI_findlink(&key->block, shapenr_act);

		if((type==-1 && kb->prev==NULL) || (type==1 && kb->next==NULL)) {
			return OPERATOR_CANCELLED;
		}

		for(kb_other= key->block.first; kb_other; kb_other= kb_other->next) {
			if(kb_other->relative == shapenr_act) {
				kb_other->relative += type;
			}
			else if(kb_other->relative == shapenr_swap) {
				kb_other->relative -= type;
			}
		}

		if(type==-1) {
			/* move back */
			kb_other= kb->prev;
			BLI_remlink(&key->block, kb);
			BLI_insertlinkbefore(&key->block, kb_other, kb);
			ob->shapenr--;
		}
		else {
			/* move next */
			kb_other= kb->next;
			BLI_remlink(&key->block, kb);
			BLI_insertlinkafter(&key->block, kb_other, kb);
			ob->shapenr++;
		}
	}

	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);

	return OPERATOR_FINISHED;
}
示例#6
0
static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
	Key *key= ob_get_key(ob);
	KeyBlock *kb= ob_get_keyblock(ob);

	if(!key || !kb)
		return OPERATOR_CANCELLED;
	
	for(kb=key->block.first; kb; kb=kb->next)
		kb->curval= 0.0f;

	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
	
	return OPERATOR_FINISHED;
}
示例#7
0
static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedData,
						   float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
{
	Key *key= ob_get_key(ob);
	KeyBlock *kb= ob_get_keyblock(ob);
	float scale[3][3];

	(void)vertexCos; /* unused */

	if(kb && kb->totelem==numVerts && kb!=key->refkey) {
		int a;

		if(ob->shapeflag & OB_SHAPE_LOCK) scale_m3_fl(scale, 1);
		else scale_m3_fl(scale, kb->curval);

		for(a=0; a<numVerts; a++)
			copy_m3_m3(defMats[a], scale);
	}

	deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
}
示例#8
0
static void deformMatricesEM(ModifierData *UNUSED(md), Object *ob,
						struct EditMesh *UNUSED(editData),
						DerivedMesh *UNUSED(derivedData),
						float (*vertexCos)[3],
						float (*defMats)[3][3],
						int numVerts)
{
	Key *key= ob_get_key(ob);
	KeyBlock *kb= ob_get_keyblock(ob);
	float scale[3][3];

	(void)vertexCos; /* unused */

	if(kb && kb->totelem==numVerts && kb!=key->refkey) {
		int a;
		scale_m3_fl(scale, kb->curval);

		for(a=0; a<numVerts; a++)
			copy_m3_m3(defMats[a], scale);
	}
}
示例#9
0
ModifierData *modifiers_getVirtualModifierList(Object *ob)
{
		/* Kinda hacky, but should be fine since we are never
	* reentrant and avoid free hassles.
		*/
	static ArmatureModifierData amd;
	static CurveModifierData cmd;
	static LatticeModifierData lmd;
	static ShapeKeyModifierData smd;
	static int init = 1;
	ModifierData *md;

	if (init) {
		md = modifier_new(eModifierType_Armature);
		amd = *((ArmatureModifierData*) md);
		modifier_free(md);

		md = modifier_new(eModifierType_Curve);
		cmd = *((CurveModifierData*) md);
		modifier_free(md);

		md = modifier_new(eModifierType_Lattice);
		lmd = *((LatticeModifierData*) md);
		modifier_free(md);

		md = modifier_new(eModifierType_ShapeKey);
		smd = *((ShapeKeyModifierData*) md);
		modifier_free(md);

		amd.modifier.mode |= eModifierMode_Virtual;
		cmd.modifier.mode |= eModifierMode_Virtual;
		lmd.modifier.mode |= eModifierMode_Virtual;
		smd.modifier.mode |= eModifierMode_Virtual;

		init = 0;
	}

	md = ob->modifiers.first;

	if(ob->parent) {
		if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) {
			amd.object = ob->parent;
			amd.modifier.next = md;
			amd.deformflag= ((bArmature *)(ob->parent->data))->deformflag;
			md = &amd.modifier;
		} else if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
			cmd.object = ob->parent;
			cmd.defaxis = ob->trackflag + 1;
			cmd.modifier.next = md;
			md = &cmd.modifier;
		} else if(ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
			lmd.object = ob->parent;
			lmd.modifier.next = md;
			md = &lmd.modifier;
		}
	}

	/* shape key modifier, not yet for curves */
	if(ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) {
		if(ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
			smd.modifier.mode |= eModifierMode_Editmode|eModifierMode_OnCage;
		else
			smd.modifier.mode &= ~eModifierMode_Editmode|eModifierMode_OnCage;

		smd.modifier.next = md;
		md = &smd.modifier;
	}

	return md;
}
示例#10
0
static int ED_object_shape_key_remove(bContext *C, Object *ob)
{
	Main *bmain= CTX_data_main(C);
	KeyBlock *kb, *rkb;
	Key *key;
	//IpoCurve *icu;

	key= ob_get_key(ob);
	if(key==NULL)
		return 0;
	
	kb= BLI_findlink(&key->block, ob->shapenr-1);

	if(kb) {
		for(rkb= key->block.first; rkb; rkb= rkb->next)
			if(rkb->relative == ob->shapenr-1)
				rkb->relative= 0;

		BLI_remlink(&key->block, kb);
		key->totkey--;
		if(key->refkey== kb) {
			key->refkey= key->block.first;

			if(key->refkey) {
				/* apply new basis key on original data */
				switch(ob->type) {
					case OB_MESH:
						key_to_mesh(key->refkey, ob->data);
						break;
					case OB_CURVE:
					case OB_SURF:
						key_to_curve(key->refkey, ob->data, BKE_curve_nurbs(ob->data));
						break;
					case OB_LATTICE:
						key_to_latt(key->refkey, ob->data);
						break;
				}
			}
		}
			
		if(kb->data) MEM_freeN(kb->data);
		MEM_freeN(kb);
		
		for(kb= key->block.first; kb; kb= kb->next)
			if(kb->adrcode>=ob->shapenr)
				kb->adrcode--;
		
#if 0 // XXX old animation system
		if(key->ipo) {
			
			for(icu= key->ipo->curve.first; icu; icu= icu->next) {
				if(icu->adrcode==ob->shapenr-1) {
					BLI_remlink(&key->ipo->curve, icu);
					free_ipo_curve(icu);
					break;
				}
			}
			for(icu= key->ipo->curve.first; icu; icu= icu->next) 
				if(icu->adrcode>=ob->shapenr)
					icu->adrcode--;
		}
#endif // XXX old animation system		
		
		if(ob->shapenr>1) ob->shapenr--;
	}
	
	if(key->totkey==0) {
		if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL;
		else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL;
		else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL;

		free_libblock_us(&(bmain->key), key);
	}
	
	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);

	return 1;
}
示例#11
0
static int object_shape_key_mirror(bContext *C, Object *ob)
{
	KeyBlock *kb;
	Key *key;

	key= ob_get_key(ob);
	if(key==NULL)
		return 0;
	
	kb= BLI_findlink(&key->block, ob->shapenr-1);

	if(kb) {
		int i1, i2;
		float *fp1, *fp2;
		float tvec[3];
		char *tag_elem= MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror");


		if(ob->type==OB_MESH) {
			Mesh *me= ob->data;
			MVert *mv;

			mesh_octree_table(ob, NULL, NULL, 's');

			for(i1=0, mv=me->mvert; i1<me->totvert; i1++, mv++) {
				i2= mesh_get_x_mirror_vert(ob, i1);
				if(i2==i1) {
					fp1= ((float *)kb->data) + i1*3;
					fp1[0] = -fp1[0];
					tag_elem[i1]= 1;
				}
				else if(i2 != -1) {
					if(tag_elem[i1]==0 && tag_elem[i2]==0) {
						fp1= ((float *)kb->data) + i1*3;
						fp2= ((float *)kb->data) + i2*3;

						copy_v3_v3(tvec,	fp1);
						copy_v3_v3(fp1,	fp2);
						copy_v3_v3(fp2,	tvec);

						/* flip x axis */
						fp1[0] = -fp1[0];
						fp2[0] = -fp2[0];
					}
					tag_elem[i1]= tag_elem[i2]= 1;
				}
			}

			mesh_octree_table(ob, NULL, NULL, 'e');
		}
		else if (ob->type == OB_LATTICE) {
			Lattice *lt= ob->data;
			int i1, i2;
			float *fp1, *fp2;
			int u, v, w;
			/* half but found up odd value */
			const int pntsu_half = (((lt->pntsu / 2) + (lt->pntsu % 2))) ;

			/* currently editmode isnt supported by mesh so
			 * ignore here for now too */

			/* if(lt->editlatt) lt= lt->editlatt->latt; */

			for(w=0; w<lt->pntsw; w++) {
				for(v=0; v<lt->pntsv; v++) {
					for(u=0; u<pntsu_half; u++) {
						int u_inv= (lt->pntsu - 1) - u;
						float tvec[3];
						if(u == u_inv) {
							i1= LT_INDEX(lt, u, v, w);
							fp1= ((float *)kb->data) + i1*3;
							fp1[0]= -fp1[0];
						}
						else {
							i1= LT_INDEX(lt, u, v, w);
							i2= LT_INDEX(lt, u_inv, v, w);

							fp1= ((float *)kb->data) + i1*3;
							fp2= ((float *)kb->data) + i2*3;

							copy_v3_v3(tvec, fp1);
							copy_v3_v3(fp1, fp2);
							copy_v3_v3(fp2, tvec);
							fp1[0]= -fp1[0];
							fp2[0]= -fp2[0];
						}
					}
				}
			}
		}

		MEM_freeN(tag_elem);
	}
	
	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);

	return 1;
}
示例#12
0
/* This function is used to loop over the keyframe data in an Object */
static short ob_keyframes_loop(KeyframeEditData *ked, Object *ob, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag)
{
	Key *key= ob_get_key(ob);
	
	/* sanity check */
	if (ob == NULL)
		return 0;
	
	/* firstly, Object's own AnimData */
	if (ob->adt) {
		if (adt_keyframes_loop(ked, ob->adt, key_ok, key_cb, fcu_cb, filterflag))
			return 1;
	}
	
	/* shapekeys */
	if ((key && key->adt) && !(filterflag & ADS_FILTER_NOSHAPEKEYS)) {
		if (adt_keyframes_loop(ked, key->adt, key_ok, key_cb, fcu_cb, filterflag))
			return 1;
	}
		
	/* Add material keyframes */
	if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) {
		int a;
		
		for (a=1; a <= ob->totcol; a++) {
			Material *ma= give_current_material(ob, a);
			
			/* there might not be a material */
			if (ELEM(NULL, ma, ma->adt)) 
				continue;
			
			/* add material's data */
			if (adt_keyframes_loop(ked, ma->adt, key_ok, key_cb, fcu_cb, filterflag))
				return 1;
		}
	}
	
	/* Add object data keyframes */
	switch (ob->type) {
		case OB_CAMERA: /* ------- Camera ------------ */
		{
			Camera *ca= (Camera *)ob->data;
			
			if ((ca->adt) && !(filterflag & ADS_FILTER_NOCAM)) {
				if (adt_keyframes_loop(ked, ca->adt, key_ok, key_cb, fcu_cb, filterflag))
					return 1;
			}
		}
			break;
		case OB_LAMP: /* ---------- Lamp ----------- */
		{
			Lamp *la= (Lamp *)ob->data;
			
			if ((la->adt) && !(filterflag & ADS_FILTER_NOLAM)) {
				if (adt_keyframes_loop(ked, la->adt, key_ok, key_cb, fcu_cb, filterflag))
					return 1;
			}
		}
			break;
		case OB_CURVE: /* ------- Curve ---------- */
		case OB_SURF: /* ------- Nurbs Surface ---------- */
		case OB_FONT: /* ------- Text Curve ---------- */
		{
			Curve *cu= (Curve *)ob->data;
			
			if ((cu->adt) && !(filterflag & ADS_FILTER_NOCUR)) {
				if (adt_keyframes_loop(ked, cu->adt, key_ok, key_cb, fcu_cb, filterflag))
					return 1;
			}
		}
			break;
		case OB_MBALL: /* ------- MetaBall ---------- */
		{
			MetaBall *mb= (MetaBall *)ob->data;
			
			if ((mb->adt) && !(filterflag & ADS_FILTER_NOMBA)) {
				if (adt_keyframes_loop(ked, mb->adt, key_ok, key_cb, fcu_cb, filterflag))
					return 1;
			}
		}
			break;
		case OB_ARMATURE: /* ------- Armature ---------- */
		{
			bArmature *arm= (bArmature *)ob->data;
			
			if ((arm->adt) && !(filterflag & ADS_FILTER_NOARM)) {
				if (adt_keyframes_loop(ked, arm->adt, key_ok, key_cb, fcu_cb, filterflag))
					return 1;
			}
		}
			break;
		case OB_MESH: /* ------- Mesh ---------- */
		{
			Mesh *me= (Mesh *)ob->data;
			
			if ((me->adt) && !(filterflag & ADS_FILTER_NOMESH)) {
				if (adt_keyframes_loop(ked, me->adt, key_ok, key_cb, fcu_cb, filterflag))
					return 1;
			}
		}
			break;
		case OB_LATTICE: /* ---- Lattice ------ */
		{
			Lattice *lt= (Lattice *)ob->data;
			
			if ((lt->adt) && !(filterflag & ADS_FILTER_NOLAT)) {
				if (adt_keyframes_loop(ked, lt->adt, key_ok, key_cb, fcu_cb, filterflag))
					return 1;
			}
		}
			break;
	}
	
	/* Add Particle System Keyframes */
	if ((ob->particlesystem.first) && !(filterflag & ADS_FILTER_NOPART)) {
		ParticleSystem *psys = ob->particlesystem.first;
		
		for(; psys; psys=psys->next) {
			if (ELEM(NULL, psys->part, psys->part->adt))
				continue;
				
			if (adt_keyframes_loop(ked, psys->part->adt, key_ok, key_cb, fcu_cb, filterflag))
				return 1;
		}
	}
	
	return 0;
}
示例#13
0
static void do_nla(Scene *scene, Object *ob, int blocktype)
{
	bPose *tpose= NULL;
	Key *key= NULL;
	ListBase tchanbase={NULL, NULL}, chanbase={NULL, NULL};
	bActionStrip *strip, *striplast=NULL, *stripfirst=NULL;
	float striptime, frametime, length, actlength;
	float blendfac, stripframe;
	float scene_cfra= BKE_curframe(scene);
	int	doit, dostride;
	
	if(blocktype==ID_AR) {
		copy_pose(&tpose, ob->pose, 1);
		rest_pose(ob->pose);		// potentially destroying current not-keyed pose
	}
	else {
		key= ob_get_key(ob);
	}
	
	/* check on extend to left or right, when no strip is hit by 'cfra' */
	for (strip=ob->nlastrips.first; strip; strip=strip->next) {
		/* escape loop on a hit */
		if( scene_cfra >= strip->start && scene_cfra <= strip->end + 0.1f)	/* note 0.1 comes back below */
			break;
		if(scene_cfra < strip->start) {
			if(stripfirst==NULL)
				stripfirst= strip;
			else if(stripfirst->start > strip->start)
				stripfirst= strip;
		}
		else if(scene_cfra > strip->end) {
			if(striplast==NULL)
				striplast= strip;
			else if(striplast->end < strip->end)
				striplast= strip;
		}
	}
	if(strip==NULL) {	/* extend */
		if(striplast)
			scene_cfra= striplast->end;
		else if(stripfirst)
			scene_cfra= stripfirst->start;
	}
	
	/* and now go over all strips */
	for (strip=ob->nlastrips.first; strip; strip=strip->next){
		doit=dostride= 0;
		
		if (strip->act && !(strip->flag & ACTSTRIP_MUTE)) {	/* so theres an action */
			
			/* Determine if the current frame is within the strip's range */
			length = strip->end-strip->start;
			actlength = strip->actend-strip->actstart;
			striptime = (scene_cfra-(strip->start)) / length;
			stripframe = (scene_cfra-(strip->start)) ;

			if (striptime>=0.0){
				
				if(blocktype==ID_AR) 
					rest_pose(tpose);
				
				/* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */
				if (striptime < 1.0f + 0.1f/length) {
					
					/* Handle path */
					if ((strip->flag & ACTSTRIP_USESTRIDE) && (blocktype==ID_AR) && (ob->ipoflag & OB_DISABLE_PATH)==0){
						Object *parent= get_parent_path(ob);
						
						if (parent) {
							Curve *cu = parent->data;
							float ctime, pdist;
							
							if (cu->flag & CU_PATH){
								/* Ensure we have a valid path */
								if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(scene, parent, 0);
								if(cu->path) {
									
									/* Find the position on the path */
									ctime= bsystem_time(scene, ob, scene_cfra, 0.0);
									
									if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
										/* correct for actions not starting on zero */
										ctime= (ctime - strip->actstart)/cu->pathlen;
										CLAMP(ctime, 0.0, 1.0);
									}
									pdist = ctime*cu->path->totdist;
									
									if(tpose && strip->stridechannel[0]) {
										striptime= stridechannel_frame(parent, ob->size[0], strip, cu->path, pdist, tpose->stride_offset);
									}									
									else {
										if (strip->stridelen) {
											striptime = pdist / strip->stridelen;
											striptime = (float)fmod (striptime+strip->actoffs, 1.0);
										}
										else
											striptime = 0;
									}
									
									frametime = (striptime * actlength) + strip->actstart;
									frametime= bsystem_time(scene, ob, frametime, 0.0);
									
									if(blocktype==ID_AR) {
										extract_pose_from_action (tpose, strip->act, frametime);
									}
									else if(blocktype==ID_OB) {
										extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
										if(key)
											extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
									}
									doit=dostride= 1;
								}
							}
						}
					}
					/* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */
					else  {
						
						/* Mod to repeat */
						if(strip->repeat!=1.0f) {
							float cycle= striptime*strip->repeat;
							
							striptime = (float)fmod (cycle, 1.0f + 0.1f/length);
							cycle-= striptime;
							
							if(blocktype==ID_AR)
								cyclic_offs_bone(ob, tpose, strip, cycle);
						}

						frametime = (striptime * actlength) + strip->actstart;
						frametime= nla_time(scene, frametime, (float)strip->repeat);
							
						if(blocktype==ID_AR) {
							extract_pose_from_action (tpose, strip->act, frametime);
						}
						else if(blocktype==ID_OB) {
							extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
							if(key)
								extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
						}
						
						doit=1;
					}
				}
				/* Handle extend */
				else {
					if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
						/* we want the strip to hold on the exact fraction of the repeat value */
						
						frametime = actlength * (strip->repeat-(int)strip->repeat);
						if(frametime<=0.000001f) frametime= actlength;	/* rounding errors... */
						frametime= bsystem_time(scene, ob, frametime+strip->actstart, 0.0);
						
						if(blocktype==ID_AR)
							extract_pose_from_action (tpose, strip->act, frametime);
						else if(blocktype==ID_OB) {
							extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
							if(key)
								extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
						}
						
						/* handle cycle hold */
						if(strip->repeat!=1.0f) {
							if(blocktype==ID_AR)
								cyclic_offs_bone(ob, tpose, strip, strip->repeat-1.0f);
						}
						
						doit=1;
					}
				}
				
				/* Handle blendin & blendout */
				if (doit){
					/* Handle blendin */
					
					if (strip->blendin>0.0 && stripframe<=strip->blendin && scene_cfra>=strip->start){
						blendfac = stripframe/strip->blendin;
					}
					else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && scene_cfra<=strip->end){
						blendfac = (length-stripframe)/(strip->blendout);
					}
					else
						blendfac = 1;
					
					if(blocktype==ID_AR) {/* Blend this pose with the accumulated pose */
						/* offset bone, for matching cycles */
						blend_pose_offset_bone (strip, ob->pose, tpose, blendfac, strip->mode);
						
						blend_poses (ob->pose, tpose, blendfac, strip->mode);
						if(dostride)
							blend_pose_strides (ob->pose, tpose, blendfac, strip->mode);
					}
					else {
						blend_ipochannels(&chanbase, &tchanbase, blendfac, strip->mode);
						BLI_freelistN(&tchanbase);
					}
				}
			}					
		}
	}
	
	if(blocktype==ID_OB) {
		execute_ipochannels(&chanbase);
	}
	else if(blocktype==ID_AR) {
		/* apply stride offset to object */
		add_v3_v3(ob->obmat[3], ob->pose->stride_offset);
	}
	
	/* free */
	if (tpose)
		free_pose(tpose);
	if(chanbase.first)
		BLI_freelistN(&chanbase);
}