예제 #1
0
static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src, float srcweight, short mode)
{
	/* matching offset bones */
	/* take dst offset, and put src on on that location */
	
	if(strip->offs_bone[0]==0)
		return;
	
	/* are we also blending with matching bones? */
	if(strip->prev && strip->start>=strip->prev->start) {
		bPoseChannel *dpchan= get_pose_channel(dst, strip->offs_bone);
		if(dpchan) {
			bPoseChannel *spchan= get_pose_channel(src, strip->offs_bone);
			if(spchan) {
				float vec[3];
				
				/* dst->ctime has the internal strip->prev action time */
				/* map this time to nla time */
				
				float ctime= get_actionstrip_frame(strip, src->ctime, 1);
				
				if( ctime > strip->prev->end) {
					bActionChannel *achan;
					
					/* add src to dest, minus the position of src on strip->prev->end */
					
					ctime= get_actionstrip_frame(strip, strip->prev->end, 0);
					
					achan= get_action_channel(strip->act, strip->offs_bone);
					if(achan && achan->ipo) {
						bPoseChannel pchan;
						/* Evaluates and sets the internal ipo value */
						calc_ipo(achan->ipo, ctime);
						/* This call also sets the pchan flags */
						execute_action_ipo(achan, &pchan);
						
						/* store offset that moves src to location of pchan */
						sub_v3_v3v3(vec, dpchan->loc, pchan.loc);
						
						mul_mat3_m4_v3(dpchan->bone->arm_mat, vec);
					}
				}
				else {
					/* store offset that moves src to location of dst */
					
					sub_v3_v3v3(vec, dpchan->loc, spchan->loc);
					mul_mat3_m4_v3(dpchan->bone->arm_mat, vec);
				}
				
				/* if blending, we only add with factor scrweight */
				mul_v3_fl(vec, srcweight);
				
				add_v3_v3(dst->cyclic_offset, vec);
			}
		}
	}
	
	add_v3_v3(dst->cyclic_offset, src->cyclic_offset);
}
예제 #2
0
PyObject* BL_ActionActuator::PyGetChannel(PyObject* value) {
	char *string= _PyUnicode_AsString(value);
	
	if (!string) {
		PyErr_SetString(PyExc_TypeError, "expected a single string");
		return NULL;
	}
	
	bPoseChannel *pchan;
	
	if(m_userpose==NULL && m_pose==NULL) {
		BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
		obj->GetPose(&m_pose); /* Get the underlying pose from the armature */
	}
	
	// get_pose_channel accounts for NULL pose, run on both incase one exists but
	// the channel doesnt
	if(		!(pchan=get_pose_channel(m_userpose, string)) &&
			!(pchan=get_pose_channel(m_pose, string))  )
	{
		PyErr_SetString(PyExc_ValueError, "channel doesnt exist");
		return NULL;
	}

	PyObject *ret = PyTuple_New(3);
	
	PyObject *list = PyList_New(3); 
	PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->loc[0]));
	PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->loc[1]));
	PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->loc[2]));
	PyTuple_SET_ITEM(ret, 0, list);
	
	list = PyList_New(3);
	PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->size[0]));
	PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->size[1]));
	PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->size[2]));
	PyTuple_SET_ITEM(ret, 1, list);
	
	list = PyList_New(4);
	PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->quat[0]));
	PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->quat[1]));
	PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->quat[2]));
	PyList_SET_ITEM(list, 3, PyFloat_FromDouble(pchan->quat[3]));
	PyTuple_SET_ITEM(ret, 2, list);

	return ret;
/*
	return Py_BuildValue("([fff][fff][ffff])",
		pchan->loc[0], pchan->loc[1], pchan->loc[2],
		pchan->size[0], pchan->size[1], pchan->size[2],
		pchan->quat[0], pchan->quat[1], pchan->quat[2], pchan->quat[3] );
*/
}
예제 #3
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++;
		}
	}
}
예제 #4
0
/* perform syncing updates for Action Groups */
static void animchan_sync_group (bAnimContext *UNUSED(ac), bAnimListElem *ale)
{
    bActionGroup *agrp= (bActionGroup *)ale->data;
    ID *owner_id= ale->id;

    /* major priority is selection status
     * so we need both a group and an owner
     */
    if (ELEM(NULL, agrp, owner_id))
        return;

    /* for standard Objects, check if group is the name of some bone */
    if (GS(owner_id->name) == ID_OB) {
        Object *ob= (Object *)owner_id;

        /* check if there are bones, and whether the name matches any
         * NOTE: this feature will only really work if groups by default contain the F-Curves for a single bone
         */
        if (ob->pose) {
            bPoseChannel *pchan= get_pose_channel(ob->pose, agrp->name);

            /* if one matches, sync the selection status */
            if (pchan) {
                if (pchan->bone->flag & BONE_SELECTED)
                    agrp->flag |= AGRP_SELECTED;
                else
                    agrp->flag &= ~AGRP_SELECTED;
            }
        }
    }
}
예제 #5
0
static int buttons_context_path_pose_bone(ButsContextPath *path)
{
	PointerRNA *ptr= &path->ptr[path->len-1];

	/* if we already have a (pinned) PoseBone, we're done */
	if(RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
		return 1;
	}

	/* if we have an armature, get the active bone */
	if(buttons_context_path_object(path)) {
		Object *ob= path->ptr[path->len-1].data;
		bArmature *arm= ob->data; /* path->ptr[path->len-1].data - works too */

		if(ob->type != OB_ARMATURE || arm->edbo) {
			return 0;
		}
		else {
			if(arm->act_bone) {
				bPoseChannel *pchan= get_pose_channel(ob->pose, arm->act_bone->name);
				if(pchan) {
					RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &path->ptr[path->len]);
					path->len++;
					return 1;
				}
			}
		}
	}

	/* no path to a bone possible */
	return 0;
}
예제 #6
0
void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node)
{
	bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);

	float mat[4][4];

	if (bone->parent) {
		// get bone-space matrix from armature-space
		bPoseChannel *parchan = get_pose_channel(ob_arm->pose, bone->parent->name);

		float invpar[4][4];
		invert_m4_m4(invpar, parchan->pose_mat);
		mult_m4_m4m4(mat, invpar, pchan->pose_mat);
	}
	else {
		copy_m4_m4(mat, pchan->pose_mat);
		// Why? Joint's localspace is still it's parent node
		//get world-space from armature-space
		//mult_m4_m4m4(mat, ob_arm->obmat, pchan->pose_mat);
	}

	// SECOND_LIFE_COMPATIBILITY
	if(export_settings->second_life)
	{
		// Remove rotations vs armature from transform
		// parent_rest_rot * mat * irest_rot
		float temp[4][4];
		copy_m4_m4(temp, bone->arm_mat);
		temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
		invert_m4(temp);

		mult_m4_m4m4(mat, mat, temp);

		if(bone->parent)
		{
			copy_m4_m4(temp, bone->parent->arm_mat);
			temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;

			mult_m4_m4m4(mat, temp, mat);
		}
	}

	TransformWriter::add_node_transform(node, mat,NULL );
}
예제 #7
0
std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id)
{
	std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;

	COLLADASW::FloatSourceF source(mSW);
	source.setId(source_id);
	source.setArrayId(source_id + ARRAY_ID_SUFFIX);
	source.setAccessorCount(BLI_countlist(defbase));
	source.setAccessorStride(16);
	
	source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
	COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
	param.push_back("TRANSFORM");

	source.prepareToAppendValues();

	bPose *pose = ob_arm->pose;
	bArmature *arm = (bArmature*)ob_arm->data;

	int flag = arm->flag;

	// put armature in rest position
	if (!(arm->flag & ARM_RESTPOS)) {
		arm->flag |= ARM_RESTPOS;
		where_is_pose(scene, ob_arm);
	}

	for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) {
		if (is_bone_defgroup(ob_arm, def)) {

			bPoseChannel *pchan = get_pose_channel(pose, def->name);

			float mat[4][4];
			float world[4][4];
			float inv_bind_mat[4][4];

			// make world-space matrix, arm_mat is armature-space
			mul_m4_m4m4(world, pchan->bone->arm_mat, ob_arm->obmat);
			
			invert_m4_m4(mat, world);
			converter.mat4_to_dae(inv_bind_mat, mat);

			source.appendValues(inv_bind_mat);
		}
	}

	// back from rest positon
	if (!(flag & ARM_RESTPOS)) {
		arm->flag = flag;
		where_is_pose(scene, ob_arm);
	}

	source.finish();

	return source_id;
}
예제 #8
0
/* Applies the appropriate stored pose from the pose-library to the current pose
 *	- assumes that a valid object, with a poselib has been supplied
 *	- gets the string to print in the header
 * 	- this code is based on the code for extract_pose_from_action in blenkernel/action.c
 */
static void poselib_apply_pose (tPoseLib_PreviewData *pld)
{
	PointerRNA *ptr= &pld->rna_ptr;
	bArmature *arm= pld->arm;
	bPose *pose= pld->pose;
	bPoseChannel *pchan;
	bAction *act= pld->act;
	bActionGroup *agrp;
	
	KeyframeEditData ked= {{NULL}};
	KeyframeEditFunc group_ok_cb;
	int frame= 1;
	
	/* get the frame */
	if (pld->marker)
		frame= pld->marker->frame;
	else
		return;	
	
	
	/* init settings for testing groups for keyframes */
	group_ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
	ked.f1= ((float)frame) - 0.5f;
	ked.f2= ((float)frame) + 0.5f;
	
	
	/* start applying - only those channels which have a key at this point in time! */
	for (agrp= act->groups.first; agrp; agrp= agrp->next) {
		/* check if group has any keyframes */
		if (ANIM_animchanneldata_keyframes_loop(&ked, NULL, agrp, ALE_GROUP, NULL, group_ok_cb, NULL)) {
			/* has keyframe on this frame, so try to get a PoseChannel with this name */
			pchan= get_pose_channel(pose, agrp->name);
			
			if (pchan) {	
				short ok= 0;
				
				/* check if this bone should get any animation applied */
				if (pld->selcount == 0) {
					/* if no bones are selected, then any bone is ok */
					ok= 1;
				}
				else if (pchan->bone) {
					/* only ok if bone is visible and selected */
					if ( (pchan->bone->flag & BONE_SELECTED) &&
						 (pchan->bone->flag & BONE_HIDDEN_P)==0 &&
						 (pchan->bone->layer & arm->layer) )
						ok = 1;
				}
				
				if (ok) 
					animsys_evaluate_action_group(ptr, act, agrp, NULL, (float)frame);
			}
		}
	}
}
예제 #9
0
void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node)
{
	bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);

	float mat[4][4];

	if (bone->parent) {
		// get bone-space matrix from armature-space
		bPoseChannel *parchan = get_pose_channel(ob_arm->pose, bone->parent->name);

		float invpar[4][4];
		invert_m4_m4(invpar, parchan->pose_mat);
		mul_m4_m4m4(mat, pchan->pose_mat, invpar);
	}
	else {
		// get world-space from armature-space
		mul_m4_m4m4(mat, pchan->pose_mat, ob_arm->obmat);
	}

	TransformWriter::add_node_transform(node, mat,NULL );
}
예제 #10
0
void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pchan)
{
	bPoseChannel *parchan = NULL;
	bPose *pose = ob_arm->pose;

	pchan = get_pose_channel(pose, bone->name);

	if (!pchan)
		return;

	parchan = pchan->parent;

	enable_fcurves(ob_arm->adt->action, bone->name);

	std::vector<float>::iterator it;
	for (it = frames.begin(); it != frames.end(); it++) {
		float mat[4][4], ipar[4][4];

		float ctime = BKE_frame_to_ctime(scene, *it);


		BKE_animsys_evaluate_animdata(scene , &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM);
		where_is_pose_bone(scene, ob_arm, pchan, ctime, 1);

		// compute bone local mat
		if (bone->parent) {
			invert_m4_m4(ipar, parchan->pose_mat);
			mult_m4_m4m4(mat, ipar, pchan->pose_mat);
		}
		else
			copy_m4_m4(mat, pchan->pose_mat);

		switch (type) {
			case 0:
				mat4_to_eul(v, mat);
				break;
			case 1:
				mat4_to_size(v, mat);
				break;
			case 2:
				copy_v3_v3(v, mat[3]);
				break;
		}

		v += 3;
	}

	enable_fcurves(ob_arm->adt->action, NULL);
}
예제 #11
0
/* Auto-keys/tags bones affected by the pose used from the poselib */
static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData *pld)
{
	bPose *pose= pld->pose;
	bPoseChannel *pchan;
	bAction *act= pld->act;
	bActionGroup *agrp;
	
	KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
	ListBase dsources = {NULL, NULL};
	short autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id);
	
	/* start tagging/keying */
	for (agrp= act->groups.first; agrp; agrp= agrp->next) {
		/* only for selected bones unless there aren't any selected, in which case all are included  */
		pchan= get_pose_channel(pose, agrp->name);
		
		if (pchan) {
			if ( (pld->selcount == 0) || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) ) {
				if (autokey) {
					/* add datasource override for the PoseChannel, to be used later */
					ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan); 
					
					/* clear any unkeyed tags */
					if (pchan->bone)
						pchan->bone->flag &= ~BONE_UNKEYED;
				}
				else {
					/* add unkeyed tags */
					if (pchan->bone)
						pchan->bone->flag |= BONE_UNKEYED;
				}
			}
		}
	}
	
	/* perform actual auto-keying now */
	if (autokey) {
		/* insert keyframes for all relevant bones in one go */
		ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
		BLI_freelistN(&dsources);
	}
	
	/* send notifiers for this */
	WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
}
예제 #12
0
static int object_hook_reset_exec(bContext *C, wmOperator *op)
{
	PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
	int num= RNA_enum_get(op->ptr, "modifier");
	Object *ob=NULL;
	HookModifierData *hmd=NULL;
	
	if (ptr.data) {		/* if modifier context is available, use that */
		ob = ptr.id.data;
		hmd= ptr.data;
	} 
	else {			/* use the provided property */
		ob = CTX_data_edit_object(C);
		hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
	}
	if (!ob || !hmd) {
		BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier");
		return OPERATOR_CANCELLED;
	}
	
	/* reset functionality */
	if(hmd->object) {
		bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
		
		if(hmd->subtarget[0] && pchan) {
			float imat[4][4], mat[4][4];
			
			/* calculate the world-space matrix for the pose-channel target first, then carry on as usual */
			mul_m4_m4m4(mat, pchan->pose_mat, hmd->object->obmat);
			
			invert_m4_m4(imat, mat);
			mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
		}
		else {
			invert_m4_m4(hmd->object->imat, hmd->object->obmat);
			mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
		}
	}
	
	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
	
	return OPERATOR_FINISHED;
}
예제 #13
0
/* dont set windows active in here, is used by renderwin too */
void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
	if(rv3d->persp==RV3D_CAMOB) {	    /* obs/camera */
		if(v3d->camera) {
			where_is_object(scene, v3d->camera);	
			obmat_to_viewmat(v3d, rv3d, v3d->camera, 0);
		}
		else {
			quat_to_mat4( rv3d->viewmat,rv3d->viewquat);
			rv3d->viewmat[3][2]-= rv3d->dist;
		}
	}
	else {
		/* should be moved to better initialize later on XXX */
		if(rv3d->viewlock)
			ED_view3d_lock(rv3d);
		
		quat_to_mat4( rv3d->viewmat,rv3d->viewquat);
		if(rv3d->persp==RV3D_PERSP) rv3d->viewmat[3][2]-= rv3d->dist;
		if(v3d->ob_centre) {
			Object *ob= v3d->ob_centre;
			float vec[3];
			
			copy_v3_v3(vec, ob->obmat[3]);
			if(ob->type==OB_ARMATURE && v3d->ob_centre_bone[0]) {
				bPoseChannel *pchan= get_pose_channel(ob->pose, v3d->ob_centre_bone);
				if(pchan) {
					copy_v3_v3(vec, pchan->pose_mat[3]);
					mul_m4_v3(ob->obmat, vec);
				}
			}
			translate_m4( rv3d->viewmat,-vec[0], -vec[1], -vec[2]);
		}
		else if (v3d->ob_centre_cursor) {
			float vec[3];
			copy_v3_v3(vec, give_cursor(scene, v3d));
			translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
		}
		else translate_m4( rv3d->viewmat,rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
	}
}
예제 #14
0
/* both poses should be in sync */
void copy_pose_result(bPose *to, bPose *from)
{
	bPoseChannel *pchanto, *pchanfrom;
	
	if(to==NULL || from==NULL) {
		printf("pose result copy error to:%p from:%p\n", (void *)to, (void *)from); // debug temp
		return;
	}

	if (to==from) {
		printf("copy_pose_result source and target are the same\n");
		return;
	}


	for(pchanfrom= from->chanbase.first; pchanfrom; pchanfrom= pchanfrom->next) {
		pchanto= get_pose_channel(to, pchanfrom->name);
		if(pchanto) {
			copy_m4_m4(pchanto->pose_mat, pchanfrom->pose_mat);
			copy_m4_m4(pchanto->chan_mat, pchanfrom->chan_mat);
			
			/* used for local constraints */
			VECCOPY(pchanto->loc, pchanfrom->loc);
			QUATCOPY(pchanto->quat, pchanfrom->quat);
			VECCOPY(pchanto->eul, pchanfrom->eul);
			VECCOPY(pchanto->size, pchanfrom->size);
			
			VECCOPY(pchanto->pose_head, pchanfrom->pose_head);
			VECCOPY(pchanto->pose_tail, pchanfrom->pose_tail);
			
			pchanto->rotmode= pchanfrom->rotmode;
			pchanto->flag= pchanfrom->flag;
			pchanto->protectflag= pchanfrom->protectflag;
		}
	}
}
예제 #15
0
void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone)
{
	bArmature *arm = (bArmature*)ob_arm->data;
	int flag = arm->flag;
	std::vector<float> fra;
	//char prefix[256];

	FCurve* fcu = (FCurve*)ob_arm->adt->action->curves.first;
	while(fcu)
	{
		std::string bone_name = getObjectBoneName(ob_arm,fcu);
		int val = BLI_strcasecmp((char*)bone_name.c_str(),bone->name);
		if(val==0) break;
		fcu = fcu->next;
	}

	if(!(fcu)) return; 
	bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);
	if (!pchan)
		return;

	find_frames(ob_arm, fra);

	if (flag & ARM_RESTPOS) {
		arm->flag &= ~ARM_RESTPOS;
		where_is_pose(scene, ob_arm);
	}

	if (fra.size()) {
		dae_baked_animation(fra ,ob_arm, bone );
	}

	if (flag & ARM_RESTPOS) 
		arm->flag = flag;
	where_is_pose(scene, ob_arm);
}
예제 #16
0
/* perform syncing updates for F-Curves */
static void animchan_sync_fcurve (bAnimContext *UNUSED(ac), bAnimListElem *ale)
{
    FCurve *fcu= (FCurve *)ale->data;
    ID *owner_id= ale->id;

    /* major priority is selection status, so refer to the checks done in anim_filter.c
     * skip_fcurve_selected_data() for reference about what's going on here...
     */
    if (ELEM3(NULL, fcu, fcu->rna_path, owner_id))
        return;

    if (GS(owner_id->name) == ID_OB) {
        Object *ob= (Object *)owner_id;

        /* only affect if F-Curve involves pose.bones */
        if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) {
            bPoseChannel *pchan;
            char *bone_name;

            /* get bone-name, and check if this bone is selected */
            bone_name= BLI_getQuotedStr(fcu->rna_path, "pose.bones[");
            pchan= get_pose_channel(ob->pose, bone_name);
            if (bone_name) MEM_freeN(bone_name);

            /* F-Curve selection depends on whether the bone is selected */
            if ((pchan) && (pchan->bone)) {
                if (pchan->bone->flag & BONE_SELECTED)
                    fcu->flag |= FCURVE_SELECTED;
                else
                    fcu->flag &= ~FCURVE_SELECTED;
            }
        }
    }
    else if (GS(owner_id->name) == ID_SCE) {
        Scene *scene = (Scene *)owner_id;

        /* only affect if F-Curve involves sequence_editor.sequences */
        if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
            Editing *ed= seq_give_editing(scene, FALSE);
            Sequence *seq;
            char *seq_name;

            /* get strip name, and check if this strip is selected */
            seq_name= BLI_getQuotedStr(fcu->rna_path, "sequences_all[");
            seq = get_seq_by_name(ed->seqbasep, seq_name, FALSE);
            if (seq_name) MEM_freeN(seq_name);

            /* can only add this F-Curve if it is selected */
            if (seq) {
                if (seq->flag & SELECT)
                    fcu->flag |= FCURVE_SELECTED;
                else
                    fcu->flag &= ~FCURVE_SELECTED;
            }
        }
    }
    else if (GS(owner_id->name) == ID_NT) {
        bNodeTree *ntree = (bNodeTree *)owner_id;

        /* check for selected nodes */
        if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
            bNode *node;
            char *node_name;

            /* get strip name, and check if this strip is selected */
            node_name= BLI_getQuotedStr(fcu->rna_path, "nodes[");
            node = nodeFindNodebyName(ntree, node_name);
            if (node_name) MEM_freeN(node_name);

            /* can only add this F-Curve if it is selected */
            if (node) {
                if (node->flag & NODE_SELECT)
                    fcu->flag |= FCURVE_SELECTED;
                else
                    fcu->flag &= ~FCURVE_SELECTED;
            }
        }
    }
}
예제 #17
0
static void deformVerts(ModifierData *md, Object *ob,
						DerivedMesh *dm,
						float (*vertexCos)[3],
						int numVerts,
						int UNUSED(useRenderParams),
						int UNUSED(isFinalCalc))
{
	HookModifierData *hmd = (HookModifierData*) md;
	bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
	float vec[3], mat[4][4], dmat[4][4];
	int i, *index_pt;
	const float falloff_squared= hmd->falloff * hmd->falloff; /* for faster comparisons */
	
	int max_dvert= 0;
	MDeformVert *dvert= NULL;
	int defgrp_index = -1;
	
	/* get world-space matrix of target, corrected for the space the verts are in */
	if (hmd->subtarget[0] && pchan) {
		/* bone target if there's a matching pose-channel */
		mul_m4_m4m4(dmat, pchan->pose_mat, hmd->object->obmat);
	}
	else {
		/* just object target */
		copy_m4_m4(dmat, hmd->object->obmat);
	}
	invert_m4_m4(ob->imat, ob->obmat);
	mul_serie_m4(mat, ob->imat, dmat, hmd->parentinv,
			 NULL, NULL, NULL, NULL, NULL);

	if((defgrp_index= defgroup_name_index(ob, hmd->name)) != -1) {
		Mesh *me = ob->data;
		if(dm) {
			dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
			if(dvert) {
				max_dvert = numVerts;
			}
		}
		else if(me->dvert) {
			dvert= me->dvert;
			if(dvert) {
				max_dvert = me->totvert;
			}
		}
	}

	/* Regarding index range checking below.
	 *
	 * This should always be true and I don't generally like 
	 * "paranoid" style code like this, but old files can have
	 * indices that are out of range because old blender did
	 * not correct them on exit editmode. - zr
	 */
	
	if(hmd->force == 0.0f) {
		/* do nothing, avoid annoying checks in the loop */
	}
	else if(hmd->indexar) { /* vertex indices? */
		const float fac_orig= hmd->force;
		float fac;
		const int *origindex_ar;

		/* if DerivedMesh is present and has original index data,
		* use it
		*/
		if(dm && (origindex_ar= dm->getVertDataArray(dm, CD_ORIGINDEX))) {
			for(i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) {
				if(*index_pt < numVerts) {
					int j;

					for(j = 0; j < numVerts; j++) {
						if(origindex_ar[j] == *index_pt) {
							float *co = vertexCos[j];
							if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
								if(dvert)
									fac *= defvert_find_weight(dvert+j, defgrp_index);

								if(fac) {
									mul_v3_m4v3(vec, mat, co);
									interp_v3_v3v3(co, co, vec, fac);
								}
							}
						}
					}
				}
			}
		}
		else { /* missing dm or ORIGINDEX */
			for(i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) {
				if(*index_pt < numVerts) {
					float *co = vertexCos[*index_pt];
					if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
						if(dvert)
							fac *= defvert_find_weight(dvert+(*index_pt), defgrp_index);

						if(fac) {
							mul_v3_m4v3(vec, mat, co);
							interp_v3_v3v3(co, co, vec, fac);
						}
					}
				}
			}
		}
	}
	else if(dvert) {	/* vertex group hook */
		int i;
		const float fac_orig= hmd->force;

		for(i = 0; i < max_dvert; i++, dvert++) {
			float fac;
			float *co = vertexCos[i];

			if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
				fac *= defvert_find_weight(dvert, defgrp_index);
				if(fac) {
					mul_v3_m4v3(vec, mat, co);
					interp_v3_v3v3(co, co, vec, fac);
				}
			}
		}
	}
}
예제 #18
0
Bone *ArmatureExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup* def)
{
	bPoseChannel *pchan = get_pose_channel(ob_arm->pose, def->name);
	return pchan ? pchan->bone : NULL;
}
예제 #19
0
파일: SkinInfo.cpp 프로젝트: BHCLL/blendocv
bPoseChannel *SkinInfo::get_pose_channel_from_node(COLLADAFW::Node *node)
{
	return get_pose_channel(ob_arm->pose, bc_get_joint_name(node));
}
예제 #20
0
/* checks validity of object pointers, and NULLs,
 * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag 
 */
static void test_constraints (Object *owner, const char substring[])
{
	bConstraint *curcon;
	ListBase *conlist= NULL;
	int type;
	
	if (owner==NULL) return;
	
	/* Check parents */
	if (strlen(substring)) {
		switch (owner->type) {
			case OB_ARMATURE:
				type = CONSTRAINT_OBTYPE_BONE;
				break;
			default:
				type = CONSTRAINT_OBTYPE_OBJECT;
				break;
		}
	}
	else
		type = CONSTRAINT_OBTYPE_OBJECT;
	
	/* Get the constraint list for this object */
	switch (type) {
		case CONSTRAINT_OBTYPE_OBJECT:
			conlist = &owner->constraints;
			break;
		case CONSTRAINT_OBTYPE_BONE:
			{
				Bone *bone;
				bPoseChannel *chan;
				
				bone = get_named_bone( ((bArmature *)owner->data), substring );
				chan = get_pose_channel(owner->pose, substring);
				if (bone && chan) {
					conlist = &chan->constraints;
				}
			}
			break;
	}
	
	/* Check all constraints - is constraint valid? */
	if (conlist) {
		for (curcon = conlist->first; curcon; curcon=curcon->next) {
			bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
			ListBase targets = {NULL, NULL};
			bConstraintTarget *ct;
			
			/* clear disabled-flag first */
			curcon->flag &= ~CONSTRAINT_DISABLE;

			if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) {
				bKinematicConstraint *data = curcon->data;
				
				/* bad: we need a separate set of checks here as poletarget is 
				 *		optional... otherwise poletarget must exist too or else
				 *		the constraint is deemed invalid
				 */
				/* default IK check ... */
				if (exist_object(data->tar) == 0) {
					data->tar = NULL;
					curcon->flag |= CONSTRAINT_DISABLE;
				}
				else if (data->tar == owner) {
					if (!get_named_bone(get_armature(owner), data->subtarget)) {
						curcon->flag |= CONSTRAINT_DISABLE;
					}
				}
				
				if (data->poletar) {
					if (exist_object(data->poletar) == 0) {
						data->poletar = NULL;
						curcon->flag |= CONSTRAINT_DISABLE;
					}
					else if (data->poletar == owner) {
						if (!get_named_bone(get_armature(owner), data->polesubtarget)) {
							curcon->flag |= CONSTRAINT_DISABLE;
						}
					}
				}
				/* ... can be overwritten here */
				BIK_test_constraint(owner, curcon);
				/* targets have already been checked for this */
				continue;
			}
			else if (curcon->type == CONSTRAINT_TYPE_ACTION) {
				bActionConstraint *data = curcon->data;
				
				/* validate action */
				if (data->act == NULL) 
					curcon->flag |= CONSTRAINT_DISABLE;
			}
			else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) {
				bFollowPathConstraint *data = curcon->data;
				
				/* don't allow track/up axes to be the same */
				if (data->upflag==data->trackflag)
					curcon->flag |= CONSTRAINT_DISABLE;
				if (data->upflag+3==data->trackflag)
					curcon->flag |= CONSTRAINT_DISABLE;
			}
			else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) {
				bTrackToConstraint *data = curcon->data;
				
				/* don't allow track/up axes to be the same */
				if (data->reserved2==data->reserved1)
					curcon->flag |= CONSTRAINT_DISABLE;
				if (data->reserved2+3==data->reserved1)
					curcon->flag |= CONSTRAINT_DISABLE;
			}
			else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) {
				bLockTrackConstraint *data = curcon->data;
				
				if (data->lockflag==data->trackflag)
					curcon->flag |= CONSTRAINT_DISABLE;
				if (data->lockflag+3==data->trackflag)
					curcon->flag |= CONSTRAINT_DISABLE;
			}
			
			/* Check targets for constraints */
			if (cti && cti->get_constraint_targets) {
				cti->get_constraint_targets(curcon, &targets);
				
				/* disable and clear constraints targets that are incorrect */
				for (ct= targets.first; ct; ct= ct->next) {
					/* general validity checks (for those constraints that need this) */
					if (exist_object(ct->tar) == 0) {
						ct->tar = NULL;
						curcon->flag |= CONSTRAINT_DISABLE;
					}
					else if (ct->tar == owner) {
						if (!get_named_bone(get_armature(owner), ct->subtarget)) {
							curcon->flag |= CONSTRAINT_DISABLE;
						}
					}
					
					/* target checks for specific constraints */
					if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) {
						if (ct->tar) {
							if (ct->tar->type != OB_CURVE) {
								ct->tar= NULL;
								curcon->flag |= CONSTRAINT_DISABLE;
							}
							else {
								Curve *cu= ct->tar->data;
								
								/* auto-set 'Path' setting on curve so this works  */
								cu->flag |= CU_PATH;
							}
						}						
					}
				}	
				
				/* free any temporary targets */
				if (cti->flush_constraint_targets)
					cti->flush_constraint_targets(curcon, &targets, 0);
			}
		}
	}
}
예제 #21
0
std::string AnimationExporter::create_4x4_source(std::vector<float> &frames , Object * ob_arm, Bone *bone , const std::string& anim_id)
{
	COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
	std::string source_id = anim_id + get_semantic_suffix(semantic);

	COLLADASW::Float4x4Source source(mSW);
	source.setId(source_id);
	source.setArrayId(source_id + ARRAY_ID_SUFFIX);
	source.setAccessorCount(frames.size());
	source.setAccessorStride(16);

	COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
	add_source_parameters(param, semantic, false, NULL, true);

	source.prepareToAppendValues();

	bPoseChannel *parchan = NULL;
	bPoseChannel *pchan = NULL;
	bPose *pose = ob_arm->pose;

	pchan = get_pose_channel(pose, bone->name);

	if (!pchan)
		return "";

	parchan = pchan->parent;

	enable_fcurves(ob_arm->adt->action, bone->name);

	std::vector<float>::iterator it;
	int j = 0;
	for (it = frames.begin(); it != frames.end(); it++) {
		float mat[4][4], ipar[4][4];

		float ctime = BKE_frame_to_ctime(scene, *it);

		BKE_animsys_evaluate_animdata(scene , &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM);
		where_is_pose_bone(scene, ob_arm, pchan, ctime, 1);

		// compute bone local mat
		if (bone->parent) {
			invert_m4_m4(ipar, parchan->pose_mat);
			mult_m4_m4m4(mat, ipar, pchan->pose_mat);
		}
		else
			copy_m4_m4(mat, pchan->pose_mat);
		UnitConverter converter;

		float outmat[4][4];
		converter.mat4_to_dae(outmat,mat);


		source.appendValues(outmat);


		j++;
	}

	enable_fcurves(ob_arm->adt->action, NULL);

	source.finish();

	return source_id;
}
예제 #22
0
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
						DerivedMesh *derivedData,
						int UNUSED(useRenderParams),
						int UNUSED(isFinalCalc))
{
	MaskModifierData *mmd= (MaskModifierData *)md;
	DerivedMesh *dm= derivedData, *result= NULL;
	GHash *vertHash=NULL, *edgeHash, *polyHash;
	GHashIterator *hashIter;
	MDeformVert *dvert= NULL, *dv;
	int numPolys=0, numLoops=0, numEdges=0, numVerts=0;
	int maxVerts, maxEdges, maxPolys;
	int i;

	MPoly *mpoly;
	MLoop *mloop;

	MPoly *mpoly_new;
	MLoop *mloop_new;
	MEdge *medge_new;
	MVert *mvert_new;


	int *loop_mapping;

	/* Overview of Method:
	 *	1. Get the vertices that are in the vertexgroup of interest 
	 *	2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
	 *	3. Make a new mesh containing only the mapping data
	 */
	
	/* get original number of verts, edges, and faces */
	maxVerts= dm->getNumVerts(dm);
	maxEdges= dm->getNumEdges(dm);
	maxPolys= dm->getNumPolys(dm);
	
	/* check if we can just return the original mesh 
	 *	- must have verts and therefore verts assigned to vgroups to do anything useful
	 */
	if ( !(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
		 (maxVerts == 0) || (ob->defbase.first == NULL) )
	{
		return derivedData;
	}
	
	/* if mode is to use selected armature bones, aggregate the bone groups */
	if (mmd->mode == MOD_MASK_MODE_ARM) { /* --- using selected bones --- */
		GHash *vgroupHash;
		Object *oba= mmd->ob_arm;
		bPoseChannel *pchan;
		bDeformGroup *def;
		char *bone_select_array;
		int bone_select_tot= 0;
		const int defbase_tot= BLI_countlist(&ob->defbase);

		/* check that there is armature object with bones to use, otherwise return original mesh */
		if (ELEM3(NULL, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first))
			return derivedData;

		bone_select_array= MEM_mallocN(defbase_tot * sizeof(char), "mask array");

		for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
			pchan = get_pose_channel(oba->pose, def->name);
			if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
				bone_select_array[i]= TRUE;
				bone_select_tot++;
			}
			else {
				bone_select_array[i]= FALSE;
			}
		}

		/* hashes for finding mapping of:
		 * 	- vgroups to indices -> vgroupHash  (string, int)
		 *	- bones to vgroup indices -> boneHash (index of vgroup, dummy)
		 */
		vgroupHash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "mask vgroup gh");
		
		/* build mapping of names of vertex groups to indices */
		for (i = 0, def = ob->defbase.first; def; def = def->next, i++) 
			BLI_ghash_insert(vgroupHash, def->name, SET_INT_IN_POINTER(i));
		
		/* if no bones selected, free hashes and return original mesh */
		if (bone_select_tot == 0) {
			BLI_ghash_free(vgroupHash, NULL, NULL);
			MEM_freeN(bone_select_array);
			
			return derivedData;
		}
		
		/* repeat the previous check, but for dverts */
		dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
		if (dvert == NULL) {
			BLI_ghash_free(vgroupHash, NULL, NULL);
			MEM_freeN(bone_select_array);
			
			return derivedData;
		}
		
		/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
		vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert gh");
		
		/* add vertices which exist in vertexgroups into vertHash for filtering */
		for (i= 0, dv= dvert; i < maxVerts; i++, dv++)
		{
			MDeformWeight *dw= dv->dw;
			int j;

			for (j= dv->totweight; j > 0; j--, dw++) {
				if (dw->def_nr < defbase_tot) {
					if (bone_select_array[dw->def_nr]) {
						if (dw->weight != 0.0f) {
							break;
						}
					}
				}
			}
			
			/* check if include vert in vertHash */
			if (mmd->flag & MOD_MASK_INV) {
				/* if this vert is in the vgroup, don't include it in vertHash */
				if (dw) continue;
			}
			else {
				/* if this vert isn't in the vgroup, don't include it in vertHash */
				if (!dw) continue;
			}
			
			/* add to ghash for verts (numVerts acts as counter for mapping) */
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
			numVerts++;
		}
		
		/* free temp hashes */
		BLI_ghash_free(vgroupHash, NULL, NULL);
		MEM_freeN(bone_select_array);
	}
	else		/* --- Using Nominated VertexGroup only --- */ 
	{
		int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
		
		/* get dverts */
		if (defgrp_index >= 0)
			dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
			
		/* if no vgroup (i.e. dverts) found, return the initial mesh */
		if ((defgrp_index < 0) || (dvert == NULL))
			return dm;
			
		/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
		vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert2 bh");
		
		/* add vertices which exist in vertexgroup into ghash for filtering */
		for (i= 0, dv= dvert; i < maxVerts; i++, dv++)
		{
			const int weight_set= defvert_find_weight(dv, defgrp_index) != 0.0f;
			
			/* check if include vert in vertHash */
			if (mmd->flag & MOD_MASK_INV) {
				/* if this vert is in the vgroup, don't include it in vertHash */
				if (weight_set) continue;
			}
			else {
				/* if this vert isn't in the vgroup, don't include it in vertHash */
				if (!weight_set) continue;
			}
			
			/* add to ghash for verts (numVerts acts as counter for mapping) */
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
			numVerts++;
		}
	}

	/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
	edgeHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask ed2 gh");
	polyHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask fa2 gh");
	
	mpoly = dm->getPolyArray(dm);
	mloop = dm->getLoopArray(dm);

	loop_mapping = MEM_callocN(sizeof(int) * maxPolys, "mask loopmap"); /* overalloc, assume all polys are seen */

	/* loop over edges and faces, and do the same thing to 
	 * ensure that they only reference existing verts 
	 */
	for (i = 0; i < maxEdges; i++) 
	{
		MEdge me;
		dm->getEdge(dm, i, &me);
		
		/* only add if both verts will be in new mesh */
		if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
			 BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)) )
		{
			BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
			numEdges++;
		}
	}
	for (i = 0; i < maxPolys; i++)
	{
		MPoly *mp = &mpoly[i];
		MLoop *ml = mloop + mp->loopstart;
		int ok = TRUE;
		int j;

		for (j = 0; j < mp->totloop; j++, ml++) {
			if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) {
				ok = FALSE;
				break;
			}
		}
		
		/* all verts must be available */
		if (ok) {
			BLI_ghash_insert(polyHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numPolys));
			loop_mapping[numPolys] = numLoops;
			numPolys++;
			numLoops += mp->totloop;
		}
	}
	
	
	/* now we know the number of verts, edges and faces, 
	 * we can create the new (reduced) mesh
	 */
	result = CDDM_from_template(dm, numVerts, numEdges, 0, numLoops, numPolys);
	
	mpoly_new = CDDM_get_polys(result);
	mloop_new = CDDM_get_loops(result);
	medge_new = CDDM_get_edges(result);
	mvert_new = CDDM_get_verts(result);
	
	/* using ghash-iterators, map data into new mesh */
		/* vertices */
	for ( hashIter = BLI_ghashIterator_new(vertHash);
		  !BLI_ghashIterator_isDone(hashIter);
		  BLI_ghashIterator_step(hashIter) ) 
	{
		MVert source;
		MVert *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		
		dm->getVert(dm, oldIndex, &source);
		dest = &mvert_new[newIndex];
		
		DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
	BLI_ghashIterator_free(hashIter);
		
		/* edges */
	for ( hashIter = BLI_ghashIterator_new(edgeHash);
		  !BLI_ghashIterator_isDone(hashIter);
		  BLI_ghashIterator_step(hashIter) ) 
	{
		MEdge source;
		MEdge *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		
		dm->getEdge(dm, oldIndex, &source);
		dest = &medge_new[newIndex];
		
		source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
		source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
		
		DM_copy_edge_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
	BLI_ghashIterator_free(hashIter);
	
		/* faces */
	for ( hashIter = BLI_ghashIterator_new(polyHash);
		  !BLI_ghashIterator_isDone(hashIter);
		  BLI_ghashIterator_step(hashIter) ) 
	{
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		MPoly *source = &mpoly[oldIndex];
		MPoly *dest = &mpoly_new[newIndex];
		int oldLoopIndex = source->loopstart;
		int newLoopIndex = loop_mapping[newIndex];
		MLoop *source_loop = &mloop[oldLoopIndex];
		MLoop *dest_loop = &mloop_new[newLoopIndex];
		
		DM_copy_poly_data(dm, result, oldIndex, newIndex, 1);
		DM_copy_loop_data(dm, result, oldLoopIndex, newLoopIndex, source->totloop);

		*dest = *source;
		dest->loopstart = newLoopIndex;
		for (i = 0; i < source->totloop; i++) {
			dest_loop[i].v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source_loop[i].v)));
			dest_loop[i].e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(source_loop[i].e)));
		}
	}

	BLI_ghashIterator_free(hashIter);

	MEM_freeN(loop_mapping);

	/* why is this needed? - campbell */
	/* recalculate normals */
	CDDM_calc_normals(result);
	
	/* free hashes */
	BLI_ghash_free(vertHash, NULL, NULL);
	BLI_ghash_free(edgeHash, NULL, NULL);
	BLI_ghash_free(polyHash, NULL, NULL);

	/* return the new mesh */
	return result;
}
예제 #23
0
void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type)
{
	bArmature *arm = (bArmature*)ob_arm->data;
	int flag = arm->flag;
	std::vector<float> fra;
	char prefix[256];

	BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone->name);

	bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);
	if (!pchan)
		return;
	//Fill frame array with key frame values framed at @param:transform_type
	switch (transform_type) {
		case 0:
			find_rotation_frames(ob_arm, fra, prefix, pchan->rotmode);
			break;
		case 1:
			find_frames(ob_arm, fra, prefix, "scale");
			break;
		case 2:
			find_frames(ob_arm, fra, prefix, "location");
			break;
		default:
			return;
	}

	// exit rest position
	if (flag & ARM_RESTPOS) {
		arm->flag &= ~ARM_RESTPOS;
		where_is_pose(scene, ob_arm);
	}
	//v array will hold all values which will be exported. 
	if (fra.size()) {
		float *values = (float*)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
		sample_animation(values, fra, transform_type, bone, ob_arm, pchan);

		if (transform_type == 0) {
			// write x, y, z curves separately if it is rotation
			float *axisValues = (float*)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");   

			for (int i = 0; i < 3; i++) {
				for (unsigned int j = 0; j < fra.size(); j++)
					axisValues[j] = values[j * 3 + i];

				dae_bone_animation(fra, axisValues, transform_type, i, id_name(ob_arm), bone->name);
			}
			MEM_freeN(axisValues);
		}
		else {
			// write xyz at once if it is location or scale
			dae_bone_animation(fra, values, transform_type, -1, id_name(ob_arm), bone->name);
		}

		MEM_freeN(values);
	}

	// restore restpos
	if (flag & ARM_RESTPOS) 
		arm->flag = flag;
	where_is_pose(scene, ob_arm);
}