2.5
Instead of many commits, here 1! - Constraint edit code back - Removed XXX stubs for constraints (make parent follow path works) - Removed XXX stubs for armature (make parent deform, do center, etc works) - Found a bad uninitialized global Scene * in code, especially in kernel it wreaked havoc. - added missing include in blenkernel/brush.c - fixed Nicholas' fix for editmode subsurf crash (It needed to check for editmode)
This commit is contained in:
		@@ -69,7 +69,9 @@ typedef struct PoseTree
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct bArmature *add_armature(char *name);
 | 
			
		||||
struct bArmature *get_armature(struct Object *ob);
 | 
			
		||||
void free_boneChildren(struct Bone *bone);
 | 
			
		||||
void free_bones (struct bArmature *arm);
 | 
			
		||||
void unlink_armature(struct bArmature *arm);
 | 
			
		||||
 
 | 
			
		||||
@@ -152,6 +152,7 @@ typedef struct ParticleEdit{
 | 
			
		||||
 | 
			
		||||
typedef struct ParticleThreadContext {
 | 
			
		||||
	/* shared */
 | 
			
		||||
	struct Scene *scene;
 | 
			
		||||
	struct Object *ob;
 | 
			
		||||
	struct DerivedMesh *dm;
 | 
			
		||||
	struct ParticleSystemModifierData *psmd;
 | 
			
		||||
@@ -243,7 +244,7 @@ void psys_find_parents(struct Object *ob, struct ParticleSystemModifierData *psm
 | 
			
		||||
 | 
			
		||||
void psys_cache_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
 | 
			
		||||
void psys_cache_child_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
 | 
			
		||||
int do_guide(struct ParticleKey *state, int pa_num, float time, struct ListBase *lb);
 | 
			
		||||
int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb);
 | 
			
		||||
float psys_get_size(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct IpoCurve *icu_size, struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleData *pa, float *vg_size);
 | 
			
		||||
float psys_get_timestep(struct ParticleSettings *part);
 | 
			
		||||
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra);
 | 
			
		||||
@@ -294,9 +295,8 @@ void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_
 | 
			
		||||
 | 
			
		||||
/* particle_system.c */
 | 
			
		||||
void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);
 | 
			
		||||
void reset_particle(struct ParticleData *pa, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct Object *ob, float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot);
 | 
			
		||||
 | 
			
		||||
void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Object *ob, struct ParticleSystem *psys, float *texco, float *force_field, float *vel,float framestep, float cfra);
 | 
			
		||||
void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float *texco, float *force_field, float *vel,float framestep, float cfra);
 | 
			
		||||
 | 
			
		||||
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
 | 
			
		||||
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node);
 | 
			
		||||
 
 | 
			
		||||
@@ -58,7 +58,7 @@
 | 
			
		||||
 | 
			
		||||
/* Structs */
 | 
			
		||||
struct Object;
 | 
			
		||||
struct Scene *scene;
 | 
			
		||||
struct Scene;
 | 
			
		||||
struct SoftBody;
 | 
			
		||||
struct ParticleSystem;
 | 
			
		||||
struct ClothModifierData;
 | 
			
		||||
 
 | 
			
		||||
@@ -87,6 +87,12 @@ bArmature *add_armature(char *name)
 | 
			
		||||
	return arm;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bArmature *get_armature(Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	if(ob->type==OB_ARMATURE)
 | 
			
		||||
		return (bArmature *)ob->data;
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void free_boneChildren(Bone *bone)
 | 
			
		||||
{ 
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@
 | 
			
		||||
#include "BLI_blenlib.h"
 | 
			
		||||
 | 
			
		||||
#include "BKE_brush.h"
 | 
			
		||||
#include "BKE_colortools.h"
 | 
			
		||||
#include "BKE_global.h"
 | 
			
		||||
#include "BKE_library.h"
 | 
			
		||||
#include "BKE_main.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -7318,7 +7318,7 @@ static DerivedMesh * explodeModifier_applyModifier(
 | 
			
		||||
				 if(emd->flag & eExplodeFlag_EdgeSplit){
 | 
			
		||||
					 int *facepa = emd->facepa;
 | 
			
		||||
					 DerivedMesh *splitdm=explodeModifier_splitEdges(emd,dm);
 | 
			
		||||
					 DerivedMesh *explode=explodeModifier_explodeMesh(emd, psmd, scene, ob, splitdm);
 | 
			
		||||
					 DerivedMesh *explode=explodeModifier_explodeMesh(emd, psmd, md->scene, ob, splitdm);
 | 
			
		||||
 | 
			
		||||
					 MEM_freeN(emd->facepa);
 | 
			
		||||
					 emd->facepa=facepa;
 | 
			
		||||
@@ -7326,7 +7326,7 @@ static DerivedMesh * explodeModifier_applyModifier(
 | 
			
		||||
					 return explode;
 | 
			
		||||
				 }
 | 
			
		||||
				 else
 | 
			
		||||
					 return explodeModifier_explodeMesh(emd, psmd, scene, ob, derivedData);
 | 
			
		||||
					 return explodeModifier_explodeMesh(emd, psmd, md->scene, ob, derivedData);
 | 
			
		||||
	}
 | 
			
		||||
	return derivedData;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -117,7 +117,7 @@
 | 
			
		||||
#include "GPU_material.h"
 | 
			
		||||
 | 
			
		||||
/* Local function protos */
 | 
			
		||||
static void solve_parenting (Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul);
 | 
			
		||||
static void solve_parenting (Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul);
 | 
			
		||||
 | 
			
		||||
float originmat[3][3];	/* after where_is_object(), can be used in other functions (bad!) */
 | 
			
		||||
 | 
			
		||||
@@ -1847,7 +1847,7 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
 | 
			
		||||
			else where_is_object_time(scene, par, ctime);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		solve_parenting(ob, par, ob->obmat, slowmat, 0);
 | 
			
		||||
		solve_parenting(scene, ob, par, ob->obmat, slowmat, 0);
 | 
			
		||||
 | 
			
		||||
		if(pop) {
 | 
			
		||||
			poplast(par);
 | 
			
		||||
@@ -1902,7 +1902,7 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
 | 
			
		||||
	else ob->transflag &= ~OB_NEG_SCALE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void solve_parenting (Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul)
 | 
			
		||||
static void solve_parenting (Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul)
 | 
			
		||||
{
 | 
			
		||||
	float totmat[4][4];
 | 
			
		||||
	float tmat[4][4];
 | 
			
		||||
@@ -1914,7 +1914,6 @@ static void solve_parenting (Object *ob, Object *par, float obmat[][4], float sl
 | 
			
		||||
	
 | 
			
		||||
	if(ob->partype & PARSLOW) Mat4CpyMat4(slowmat, obmat);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	switch(ob->partype & PARTYPE) {
 | 
			
		||||
	case PAROBJECT:
 | 
			
		||||
		ok= 0;
 | 
			
		||||
@@ -2036,7 +2035,7 @@ for a lamp that is the child of another object */
 | 
			
		||||
	if(ob->parent) {
 | 
			
		||||
		par= ob->parent;
 | 
			
		||||
		
 | 
			
		||||
		solve_parenting(ob, par, ob->obmat, slowmat, 1);
 | 
			
		||||
		solve_parenting(scene, ob, par, ob->obmat, slowmat, 1);
 | 
			
		||||
 | 
			
		||||
		if(ob->partype & PARSLOW) {
 | 
			
		||||
 | 
			
		||||
@@ -2273,7 +2272,11 @@ void object_handle_update(Scene *scene, Object *ob)
 | 
			
		||||
			
 | 
			
		||||
			/* includes all keys and modifiers */
 | 
			
		||||
			if(ob->type==OB_MESH) {
 | 
			
		||||
				makeDerivedMesh(scene, ob, ((Mesh*)ob->data)->edit_mesh, CD_MASK_BAREMESH);	// here was vieweditdatamask? XXX
 | 
			
		||||
					// here was vieweditdatamask? XXX
 | 
			
		||||
				if(ob==scene->obedit)
 | 
			
		||||
					makeDerivedMesh(scene, ob, ((Mesh*)ob->data)->edit_mesh, CD_MASK_BAREMESH);
 | 
			
		||||
				else
 | 
			
		||||
					makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH);
 | 
			
		||||
			}
 | 
			
		||||
			else if(ob->type==OB_MBALL) {
 | 
			
		||||
				makeDispListMBall(scene, ob);
 | 
			
		||||
 
 | 
			
		||||
@@ -1408,6 +1408,7 @@ static float vert_weight(MDeformVert *dvert, int group)
 | 
			
		||||
	}
 | 
			
		||||
	return 0.0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_prekink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, short type, short axis, float obmat[][4])
 | 
			
		||||
{
 | 
			
		||||
	float vec[3]={0.0,0.0,0.0}, q1[4]={1,0,0,0},q2[4];
 | 
			
		||||
@@ -1542,6 +1543,7 @@ static void do_prekink(ParticleKey *state, ParticleKey *par, float *par_rot, flo
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump)
 | 
			
		||||
{
 | 
			
		||||
	if(par && clumpfac!=0.0){
 | 
			
		||||
@@ -1559,7 +1561,8 @@ static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clu
 | 
			
		||||
		VecLerpf(state->co,state->co,par->co,clump);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
int do_guide(ParticleKey *state, int pa_num, float time, ListBase *lb)
 | 
			
		||||
 | 
			
		||||
int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase *lb)
 | 
			
		||||
{
 | 
			
		||||
	PartDeflect *pd;
 | 
			
		||||
	ParticleEffectorCache *ec;
 | 
			
		||||
@@ -1717,7 +1720,7 @@ static void do_rough_end(float *loc, float t, float fac, float shape, ParticleKe
 | 
			
		||||
 | 
			
		||||
	VECADD(state->co,state->co,rough);
 | 
			
		||||
}
 | 
			
		||||
static void do_path_effectors(Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
 | 
			
		||||
static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
 | 
			
		||||
{
 | 
			
		||||
	float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
 | 
			
		||||
	ParticleKey eff_key;
 | 
			
		||||
@@ -1728,7 +1731,7 @@ static void do_path_effectors(Object *ob, ParticleSystem *psys, int i, ParticleC
 | 
			
		||||
	QUATCOPY(eff_key.rot,(ca-1)->rot);
 | 
			
		||||
 | 
			
		||||
	pa= psys->particles+i;
 | 
			
		||||
	do_effectors(i, pa, &eff_key, ob, psys, rootco, force, vel, dfra, cfra);
 | 
			
		||||
	do_effectors(i, pa, &eff_key, scene, ob, psys, rootco, force, vel, dfra, cfra);
 | 
			
		||||
 | 
			
		||||
	VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
 | 
			
		||||
 | 
			
		||||
@@ -2117,7 +2120,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
 | 
			
		||||
	if(part->flag & PART_CHILD_EFFECT) {
 | 
			
		||||
		for(k=0,state=keys; k<=ctx->steps; k++,state++) {
 | 
			
		||||
			if(k) {
 | 
			
		||||
				do_path_effectors(ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, pa_effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
 | 
			
		||||
				do_path_effectors(ctx->scene, ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, pa_effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				VecSubf(eff_vec,(state+1)->co,state->co);
 | 
			
		||||
@@ -2144,7 +2147,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
 | 
			
		||||
		/* apply different deformations to the child path */
 | 
			
		||||
		if(part->flag & PART_CHILD_EFFECT)
 | 
			
		||||
			/* state is safe to cast, since only co and vel are used */
 | 
			
		||||
			guided = do_guide((ParticleKey*)state, cpa->parent, t, &(psys->effectors));
 | 
			
		||||
			guided = do_guide(ctx->scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors));
 | 
			
		||||
 | 
			
		||||
		if(guided==0){
 | 
			
		||||
			if(part->kink)
 | 
			
		||||
@@ -2575,12 +2578,12 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
 | 
			
		||||
		for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
 | 
			
		||||
			/* apply effectors */
 | 
			
		||||
			if(!(psys->part->flag & PART_CHILD_EFFECT) && edit==0 && k)
 | 
			
		||||
				do_path_effectors(ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
 | 
			
		||||
				do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
 | 
			
		||||
 | 
			
		||||
			/* apply guide curves to path data */
 | 
			
		||||
			if(edit==0 && psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
 | 
			
		||||
				/* ca is safe to cast, since only co and vel are used */
 | 
			
		||||
				do_guide((ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
 | 
			
		||||
				do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
 | 
			
		||||
 | 
			
		||||
			/* apply lattice */
 | 
			
		||||
			if(psys->lattice && edit==0)
 | 
			
		||||
@@ -3468,7 +3471,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
 | 
			
		||||
				Mat4Mul3Vecfl(hairmat, state->vel);
 | 
			
		||||
 | 
			
		||||
				if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) {
 | 
			
		||||
					do_guide(state, p, state->time, &psys->effectors);
 | 
			
		||||
					do_guide(scene, state, p, state->time, &psys->effectors);
 | 
			
		||||
					/* TODO: proper velocity handling */
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1458,6 +1458,7 @@ ParticleThread *psys_threads_create(struct Scene *scene, struct Object *ob, stru
 | 
			
		||||
	threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
 | 
			
		||||
	ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
 | 
			
		||||
 | 
			
		||||
	ctx->scene= scene;
 | 
			
		||||
	ctx->ob= ob;
 | 
			
		||||
	ctx->psys= psys;
 | 
			
		||||
	ctx->psmd= psys_get_modifier(ob, psys);
 | 
			
		||||
@@ -1684,7 +1685,7 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/* sets particle to the emitter surface with initial velocity & rotation */
 | 
			
		||||
void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifierData *psmd, Object *ob,
 | 
			
		||||
static void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, ParticleSystemModifierData *psmd, Object *ob,
 | 
			
		||||
					float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot)
 | 
			
		||||
{
 | 
			
		||||
	ParticleSettings *part;
 | 
			
		||||
@@ -1924,7 +1925,7 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
 | 
			
		||||
	pa->stick_ob = 0;
 | 
			
		||||
	pa->flag &= ~PARS_STICKY;
 | 
			
		||||
}
 | 
			
		||||
static void reset_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from)
 | 
			
		||||
static void reset_all_particles(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from)
 | 
			
		||||
{
 | 
			
		||||
	ParticleData *pa;
 | 
			
		||||
	int p, totpart=psys->totpart;
 | 
			
		||||
@@ -1933,7 +1934,7 @@ static void reset_all_particles(Object *ob, ParticleSystem *psys, ParticleSystem
 | 
			
		||||
	float *vg_rot=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
 | 
			
		||||
	
 | 
			
		||||
	for(p=from, pa=psys->particles+from; p<totpart; p++, pa++)
 | 
			
		||||
		reset_particle(pa, psys, psmd, ob, dtime, cfra, vg_vel, vg_tan, vg_rot);
 | 
			
		||||
		reset_particle(scene, pa, psys, psmd, ob, dtime, cfra, vg_vel, vg_tan, vg_rot);
 | 
			
		||||
 | 
			
		||||
	if(vg_vel)
 | 
			
		||||
		MEM_freeN(vg_vel);
 | 
			
		||||
@@ -1993,7 +1994,7 @@ int psys_count_keyed_targets(Object *ob, ParticleSystem *psys)
 | 
			
		||||
	return select;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_keyed_keys(Object *ob, ParticleSystem *psys)
 | 
			
		||||
static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
 | 
			
		||||
{
 | 
			
		||||
	Object *kob = ob;
 | 
			
		||||
	ParticleSystem *kpsys = psys;
 | 
			
		||||
@@ -2291,7 +2292,7 @@ static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla,
 | 
			
		||||
 | 
			
		||||
	VecAddf(field,field,mag_vec);
 | 
			
		||||
}
 | 
			
		||||
static void add_to_effectors(ListBase *lb, Object *ob, Object *obsrc, ParticleSystem *psys)
 | 
			
		||||
static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obsrc, ParticleSystem *psys)
 | 
			
		||||
{
 | 
			
		||||
	ParticleEffectorCache *ec;
 | 
			
		||||
	PartDeflect *pd= ob->pd;
 | 
			
		||||
@@ -2374,7 +2375,7 @@ static void add_to_effectors(ListBase *lb, Object *ob, Object *obsrc, ParticleSy
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void psys_init_effectors_recurs(Object *ob, Object *obsrc, ParticleSystem *psys, ListBase *listb, int level)
 | 
			
		||||
static void psys_init_effectors_recurs(Scene *scene, Object *ob, Object *obsrc, ParticleSystem *psys, ListBase *listb, int level)
 | 
			
		||||
{
 | 
			
		||||
	Group *group;
 | 
			
		||||
	GroupObject *go;
 | 
			
		||||
@@ -2384,12 +2385,12 @@ static void psys_init_effectors_recurs(Object *ob, Object *obsrc, ParticleSystem
 | 
			
		||||
 | 
			
		||||
	if(ob->lay & layer) {
 | 
			
		||||
		if(ob->pd || ob->particlesystem.first)
 | 
			
		||||
			add_to_effectors(listb, ob, obsrc, psys);
 | 
			
		||||
			add_to_effectors(listb, scene, ob, obsrc, psys);
 | 
			
		||||
 | 
			
		||||
		if(ob->dup_group) {
 | 
			
		||||
			group= ob->dup_group;
 | 
			
		||||
			for(go= group->gobject.first; go; go= go->next)
 | 
			
		||||
				psys_init_effectors_recurs(go->ob, obsrc, psys, listb, level+1);
 | 
			
		||||
				psys_init_effectors_recurs(scene, go->ob, obsrc, psys, listb, level+1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -2405,11 +2406,11 @@ void psys_init_effectors(Scene *scene, Object *obsrc, Group *group, ParticleSyst
 | 
			
		||||
		GroupObject *go;
 | 
			
		||||
		
 | 
			
		||||
		for(go= group->gobject.first; go; go= go->next)
 | 
			
		||||
			psys_init_effectors_recurs(go->ob, obsrc, psys, listb, 0);
 | 
			
		||||
			psys_init_effectors_recurs(scene, go->ob, obsrc, psys, listb, 0);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		for(base = scene->base.first; base; base= base->next)
 | 
			
		||||
			psys_init_effectors_recurs(base->object, obsrc, psys, listb, 0);
 | 
			
		||||
			psys_init_effectors_recurs(scene, base->object, obsrc, psys, listb, 0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2446,7 +2447,7 @@ void psys_end_effectors(ParticleSystem *psys)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
 | 
			
		||||
static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
 | 
			
		||||
{
 | 
			
		||||
	ListBase *lb=&psys->effectors;
 | 
			
		||||
	ParticleEffectorCache *ec;
 | 
			
		||||
@@ -2523,7 +2524,7 @@ static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemMo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* calculate forces that all effectors apply to a particle*/
 | 
			
		||||
void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, ParticleSystem *psys, float *rootco, float *force_field, float *vel,float framestep, float cfra)
 | 
			
		||||
void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, Object *ob, ParticleSystem *psys, float *rootco, float *force_field, float *vel,float framestep, float cfra)
 | 
			
		||||
{
 | 
			
		||||
	Object *eob;
 | 
			
		||||
	ParticleSystem *epsys;
 | 
			
		||||
@@ -2641,7 +2642,7 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P
 | 
			
		||||
/*			Newtonian physics					*/
 | 
			
		||||
/************************************************/
 | 
			
		||||
/* gathers all forces that effect particles and calculates a new state for the particle */
 | 
			
		||||
static void apply_particle_forces(int pa_no, ParticleData *pa, Object *ob, ParticleSystem *psys, ParticleSettings *part, float timestep, float dfra, float cfra)
 | 
			
		||||
static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Object *ob, ParticleSystem *psys, ParticleSettings *part, float timestep, float dfra, float cfra)
 | 
			
		||||
{
 | 
			
		||||
	ParticleKey states[5], tkey;
 | 
			
		||||
	float force[3],tvel[3],dx[4][3],dv[4][3];
 | 
			
		||||
@@ -2673,7 +2674,7 @@ static void apply_particle_forces(int pa_no, ParticleData *pa, Object *ob, Parti
 | 
			
		||||
		tvel[0]=tvel[1]=tvel[2]=0.0;
 | 
			
		||||
		/* add effectors */
 | 
			
		||||
		if(part->type != PART_HAIR)
 | 
			
		||||
			do_effectors(pa_no,pa,states+i,ob,psys,states->co,force,tvel,dfra,fra);
 | 
			
		||||
			do_effectors(pa_no,pa,states+i,scene, ob, psys,states->co,force,tvel,dfra,fra);
 | 
			
		||||
 | 
			
		||||
		/* calculate air-particle interaction */
 | 
			
		||||
		if(part->dragfac!=0.0f){
 | 
			
		||||
@@ -2777,7 +2778,7 @@ static void apply_particle_forces(int pa_no, ParticleData *pa, Object *ob, Parti
 | 
			
		||||
	tkey.time=pa->state.time;
 | 
			
		||||
 | 
			
		||||
	if(part->type != PART_HAIR) {
 | 
			
		||||
		if(do_guide(&tkey,pa_no,time,&psys->effectors)) {
 | 
			
		||||
		if(do_guide(scene, &tkey, pa_no, time, &psys->effectors)) {
 | 
			
		||||
			VECCOPY(pa->state.co,tkey.co);
 | 
			
		||||
			/* guides don't produce valid velocity */
 | 
			
		||||
			VECSUB(pa->state.vel,tkey.co,pa->prev_state.co);
 | 
			
		||||
@@ -3054,7 +3055,7 @@ static void particle_intersect_face(void *userdata, int index, const BVHTreeRay
 | 
			
		||||
/* angular momentum <-> linear momentum and swept sphere - mesh collisions */
 | 
			
		||||
/* 1. check for all possible deflectors for closest intersection on particle path */
 | 
			
		||||
/* 2. if deflection was found kill the particle or calculate new coordinates */
 | 
			
		||||
static void deflect_particle(Object *pob, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, int p, float timestep, float dfra, float cfra){
 | 
			
		||||
static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, int p, float timestep, float dfra, float cfra){
 | 
			
		||||
	Object *ob = NULL;
 | 
			
		||||
	ListBase *lb=&psys->effectors;
 | 
			
		||||
	ParticleEffectorCache *ec;
 | 
			
		||||
@@ -3259,7 +3260,7 @@ static void deflect_particle(Object *pob, ParticleSystemModifierData *psmd, Part
 | 
			
		||||
/************************************************/
 | 
			
		||||
/*			Boid physics						*/
 | 
			
		||||
/************************************************/
 | 
			
		||||
static int boid_see_mesh(ListBase *lb, Object *pob, ParticleSystem *psys, float *vec1, float *vec2, float *loc, float *nor, float cfra)
 | 
			
		||||
static int boid_see_mesh(ListBase *lb, Scene *scene, Object *pob, ParticleSystem *psys, float *vec1, float *vec2, float *loc, float *nor, float cfra)
 | 
			
		||||
{
 | 
			
		||||
	Object *ob, *min_ob;
 | 
			
		||||
	DerivedMesh *dm;
 | 
			
		||||
@@ -3450,7 +3451,7 @@ static void boid_brain(BoidVecFunc *bvf, ParticleData *pa, Scene *scene, Object
 | 
			
		||||
				bvf->Copyf(dvec,pa->prev_state.vel);
 | 
			
		||||
				bvf->Mulf(dvec,5.0f);
 | 
			
		||||
				bvf->Addf(dvec,dvec,pa->prev_state.co);
 | 
			
		||||
				if(boid_see_mesh(&psys->effectors,ob,psys,pa->prev_state.co,dvec,ob_co,ob_nor,cfra)){
 | 
			
		||||
				if(boid_see_mesh(&psys->effectors,scene, ob,psys,pa->prev_state.co,dvec,ob_co,ob_nor,cfra)){
 | 
			
		||||
					float probelen = bvf->Length(dvec);
 | 
			
		||||
					float proj;
 | 
			
		||||
					float oblen;
 | 
			
		||||
@@ -3696,7 +3697,7 @@ static void boid_brain(BoidVecFunc *bvf, ParticleData *pa, Scene *scene, Object
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/* tries to realize the wanted acceleration */
 | 
			
		||||
static void boid_body(BoidVecFunc *bvf, ParticleData *pa, ParticleSystem *psys, ParticleSettings *part, float timestep, float *acc)
 | 
			
		||||
static void boid_body(Scene *scene, BoidVecFunc *bvf, ParticleData *pa, ParticleSystem *psys, ParticleSettings *part, float timestep, float *acc)
 | 
			
		||||
{
 | 
			
		||||
	float dvec[3], bvec[3], length, max_vel=part->max_vel;
 | 
			
		||||
	float q2[4], q[4];
 | 
			
		||||
@@ -3920,7 +3921,7 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
 | 
			
		||||
/*			System Core							*/
 | 
			
		||||
/************************************************/
 | 
			
		||||
/* unbaked particles are calculated dynamically */
 | 
			
		||||
static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra,
 | 
			
		||||
static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra,
 | 
			
		||||
						  float *vg_vel, float *vg_tan, float *vg_rot, float *vg_size)
 | 
			
		||||
{
 | 
			
		||||
	ParticleData *pa;
 | 
			
		||||
@@ -3968,7 +3969,7 @@ static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifi
 | 
			
		||||
			}
 | 
			
		||||
			pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
 | 
			
		||||
 | 
			
		||||
			reset_particle(pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
 | 
			
		||||
			reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
 | 
			
		||||
 | 
			
		||||
			if(cfra>pa->time && part->flag & PART_LOOP && part->type!=PART_HAIR){
 | 
			
		||||
				pa->loop=(short)((cfra-pa->time)/pa->lifetime);
 | 
			
		||||
@@ -4001,7 +4002,7 @@ static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifi
 | 
			
		||||
		psys_init_effectors(scene, ob, part->eff_group, psys);
 | 
			
		||||
		
 | 
			
		||||
		if(psys->effectors.first)
 | 
			
		||||
			precalc_effectors(ob,psys,psmd,cfra);
 | 
			
		||||
			precalc_effectors(scene, ob,psys,psmd,cfra);
 | 
			
		||||
 | 
			
		||||
		if(part->phystype==PART_PHYS_BOIDS){
 | 
			
		||||
			/* create particle tree for fast inter-particle comparisons */
 | 
			
		||||
@@ -4042,7 +4043,7 @@ static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifi
 | 
			
		||||
				|| pa->alive==PARS_KILLED
 | 
			
		||||
				|| ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
 | 
			
		||||
				|| birthtime >= cfra){
 | 
			
		||||
				reset_particle(pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
 | 
			
		||||
				reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			pa_dfra = dfra;
 | 
			
		||||
@@ -4069,10 +4070,10 @@ static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifi
 | 
			
		||||
				switch(part->phystype){
 | 
			
		||||
					case PART_PHYS_NEWTON:
 | 
			
		||||
						/* do global forces & effectors */
 | 
			
		||||
						apply_particle_forces(p,pa,ob,psys,part,timestep,pa_dfra,cfra);
 | 
			
		||||
						apply_particle_forces(scene, p, pa, ob, psys, part, timestep,pa_dfra,cfra);
 | 
			
		||||
			
 | 
			
		||||
						/* deflection */
 | 
			
		||||
						deflect_particle(ob,psmd,psys,part,pa,p,timestep,pa_dfra,cfra);
 | 
			
		||||
						deflect_particle(scene, ob,psmd,psys,part,pa,p,timestep,pa_dfra,cfra);
 | 
			
		||||
 | 
			
		||||
						/* rotations */
 | 
			
		||||
						rotate_particle(part,pa,pa_dfra,timestep);
 | 
			
		||||
@@ -4082,7 +4083,7 @@ static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifi
 | 
			
		||||
						float acc[3];
 | 
			
		||||
						boid_brain(&bvf, pa, scene, ob, psys, part, tree, timestep,cfra,acc);
 | 
			
		||||
						if(pa->alive != PARS_DYING)
 | 
			
		||||
							boid_body(&bvf,pa,psys,part,timestep,acc);
 | 
			
		||||
							boid_body(scene, &bvf,pa,psys,part,timestep,acc);
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
@@ -4092,7 +4093,7 @@ static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifi
 | 
			
		||||
 | 
			
		||||
					if(part->flag & PART_LOOP && part->type!=PART_HAIR){
 | 
			
		||||
						pa->loop++;
 | 
			
		||||
						reset_particle(pa,psys,psmd,ob,0.0,cfra,vg_vel,vg_tan,vg_rot);
 | 
			
		||||
						reset_particle(scene, pa,psys,psmd,ob,0.0,cfra,vg_vel,vg_tan,vg_rot);
 | 
			
		||||
						pa->alive=PARS_ALIVE;
 | 
			
		||||
					}
 | 
			
		||||
					else{
 | 
			
		||||
@@ -4183,7 +4184,7 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
 | 
			
		||||
 | 
			
		||||
	psys_init_effectors(scene, ob, part->eff_group, psys);
 | 
			
		||||
	if(psys->effectors.first)
 | 
			
		||||
		precalc_effectors(ob,psys,psmd,cfra);
 | 
			
		||||
		precalc_effectors(scene, ob,psys,psmd,cfra);
 | 
			
		||||
		
 | 
			
		||||
	if(psys_in_edit_mode(scene, psys))
 | 
			
		||||
		; //XXX PE_recalc_world_cos(ob, psys);
 | 
			
		||||
@@ -4211,7 +4212,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
 | 
			
		||||
	//if(part->flag & (PART_BAKED_GUIDES+PART_BAKED_DEATHS)){
 | 
			
		||||
		psys_init_effectors(scene, ob, part->eff_group, psys);
 | 
			
		||||
		if(psys->effectors.first)
 | 
			
		||||
			precalc_effectors(ob,psys,psmd,cfra);
 | 
			
		||||
			precalc_effectors(scene, ob,psys,psmd,cfra);
 | 
			
		||||
	//}
 | 
			
		||||
	
 | 
			
		||||
	disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
 | 
			
		||||
@@ -4518,7 +4519,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 | 
			
		||||
			initialize_all_particles(ob, psys, psmd);
 | 
			
		||||
 | 
			
		||||
			if(alloc)
 | 
			
		||||
				reset_all_particles(ob, psys, psmd, 0.0, cfra, oldtotpart);
 | 
			
		||||
				reset_all_particles(scene, ob, psys, psmd, 0.0, cfra, oldtotpart);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* flag for possible explode modifiers after this system */
 | 
			
		||||
@@ -4530,7 +4531,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 | 
			
		||||
		if(get_particles_from_cache(ob, psys, framenr)) {
 | 
			
		||||
			if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
 | 
			
		||||
				psys_count_keyed_targets(ob,psys);
 | 
			
		||||
				set_keyed_keys(ob, psys);
 | 
			
		||||
				set_keyed_keys(scene, ob, psys);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cached_step(scene, ob, psmd, psys, cfra);
 | 
			
		||||
@@ -4600,7 +4601,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 | 
			
		||||
 | 
			
		||||
		for(dframe=-totframesback; dframe<=0; dframe++) {
 | 
			
		||||
			/* ok now we're all set so let's go */
 | 
			
		||||
			dynamics_step(ob,psys,psmd,cfra+dframe,vg_vel,vg_tan,vg_rot,vg_size);
 | 
			
		||||
			dynamics_step(scene, ob, psys, psmd, cfra+dframe, vg_vel, vg_tan, vg_rot, vg_size);
 | 
			
		||||
			psys->cfra = cfra+dframe;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -4617,7 +4618,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 | 
			
		||||
 | 
			
		||||
	/* for keyed particles the path is allways known so it can be drawn */
 | 
			
		||||
	if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED){
 | 
			
		||||
		set_keyed_keys(ob, psys);
 | 
			
		||||
		set_keyed_keys(scene, ob, psys);
 | 
			
		||||
		psys_update_path_cache(scene, ob, psmd, psys,(int)cfra);
 | 
			
		||||
	}
 | 
			
		||||
	else if(psys->pathcache)
 | 
			
		||||
 
 | 
			
		||||
@@ -3567,7 +3567,7 @@ static void springs_from_particles(Object *ob)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void particles_to_softbody(Object *ob)
 | 
			
		||||
static void particles_to_softbody(Scene *scene, Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	SoftBody *sb;
 | 
			
		||||
	BodyPoint *bp;
 | 
			
		||||
@@ -4111,7 +4111,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
 | 
			
		||||
	   ((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) {
 | 
			
		||||
 | 
			
		||||
		if(sb->particles){
 | 
			
		||||
			particles_to_softbody(ob);
 | 
			
		||||
			particles_to_softbody(scene, ob);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			switch(ob->type) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3856,7 +3856,7 @@ void add_verts_to_dgroups(Scene *scene, Object *ob, Object *par, int heat, int m
 | 
			
		||||
	 * when parenting, or simply the original mesh coords.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	bArmature *arm= ob->data;
 | 
			
		||||
	bArmature *arm= par->data;
 | 
			
		||||
	Bone **bonelist, *bone;
 | 
			
		||||
	bDeformGroup **dgrouplist, **dgroupflip;
 | 
			
		||||
	bDeformGroup *dgroup, *curdg;
 | 
			
		||||
@@ -4020,7 +4020,7 @@ void create_vgroups_from_armature(Scene *scene, Object *ob, Object *par)
 | 
			
		||||
	/* Lets try to create some vertex groups 
 | 
			
		||||
	 * based on the bones of the parent armature.
 | 
			
		||||
	 */
 | 
			
		||||
	bArmature *arm= ob->data;
 | 
			
		||||
	bArmature *arm= par->data;
 | 
			
		||||
	short mode;
 | 
			
		||||
 | 
			
		||||
	/* Prompt the user on whether/how they want the vertex groups
 | 
			
		||||
@@ -4030,6 +4030,9 @@ void create_vgroups_from_armature(Scene *scene, Object *ob, Object *par)
 | 
			
		||||
				  "Name Groups %x2|"
 | 
			
		||||
                  "Create From Envelopes %x3|"
 | 
			
		||||
				  "Create From Bone Heat %x4|");
 | 
			
		||||
	
 | 
			
		||||
	mode= 3; // XXX
 | 
			
		||||
	
 | 
			
		||||
	switch (mode) {
 | 
			
		||||
	case 2:
 | 
			
		||||
		/* Traverse the bone list, trying to create empty vertex 
 | 
			
		||||
 
 | 
			
		||||
@@ -95,6 +95,9 @@ struct Bone *get_indexed_bone (struct Object *ob, int index);
 | 
			
		||||
float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]);
 | 
			
		||||
 | 
			
		||||
void transform_armature_mirror_update(struct Object *obedit);
 | 
			
		||||
void clear_armature(struct Scene *scene, struct Object *ob, char mode);
 | 
			
		||||
void create_vgroups_from_armature(struct Scene *scene, struct Object *ob, struct Object *par);
 | 
			
		||||
void docenter_armature (struct Scene *scene, struct View3D *v3d, struct Object *ob, int centermode);
 | 
			
		||||
 | 
			
		||||
/* poseobject.c */
 | 
			
		||||
void ED_armature_exit_posemode(struct Base *base);
 | 
			
		||||
 
 | 
			
		||||
@@ -106,6 +106,7 @@ void		EM_select_face_fgon(struct EditMesh *em, struct EditFace *efa, int val);
 | 
			
		||||
void		EM_selectmode_flush(struct EditMesh *em);
 | 
			
		||||
void		EM_deselect_flush(struct EditMesh *em);
 | 
			
		||||
void		EM_selectmode_set(struct EditMesh *em);
 | 
			
		||||
void		EM_select_flush(struct EditMesh *em);
 | 
			
		||||
void		EM_convertsel(struct EditMesh *em, short oldmode, short selectmode);
 | 
			
		||||
			
 | 
			
		||||
			/* exported to transform */
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ struct Object;
 | 
			
		||||
struct bContext;
 | 
			
		||||
struct Base;
 | 
			
		||||
struct View3D;
 | 
			
		||||
struct bConstraint;
 | 
			
		||||
 | 
			
		||||
void ED_operatortypes_object(void);
 | 
			
		||||
void ED_keymap_object(struct wmWindowManager *wm);
 | 
			
		||||
@@ -57,10 +58,14 @@ void ED_object_enter_editmode(struct bContext *C, int flag);
 | 
			
		||||
 | 
			
		||||
void ED_object_base_init_from_view(struct Scene *scene, struct View3D *v3d, struct Base *base);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* cleanup */
 | 
			
		||||
int object_data_is_libdata(struct Object *ob);
 | 
			
		||||
int object_is_libdata(struct Object *ob);
 | 
			
		||||
 | 
			
		||||
/* constraints */
 | 
			
		||||
struct bConstraint *add_new_constraint (short type);
 | 
			
		||||
void add_constraint_to_object (struct bConstraint *con, struct Object *ob);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* ED_OBJECT_H */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,6 @@ void EM_remove_selection(EditMesh *em, void *data, int type);
 | 
			
		||||
void EM_set_actFace(EditMesh *em, EditFace *efa);
 | 
			
		||||
void EM_select_face(EditFace *efa, int sel);
 | 
			
		||||
void EM_clear_flag_all(EditMesh *em, int flag);
 | 
			
		||||
void EM_select_flush(EditMesh *em);
 | 
			
		||||
void EM_set_flag_all(EditMesh *em, int flag);
 | 
			
		||||
 | 
			
		||||
void EM_add_data_layer(EditMesh *em, CustomData *data, int type);
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,7 @@ CPPFLAGS += -I../../blenloader
 | 
			
		||||
CPPFLAGS += -I../../blenlib
 | 
			
		||||
CPPFLAGS += -I../../makesdna
 | 
			
		||||
CPPFLAGS += -I../../makesrna
 | 
			
		||||
CPPFLAGS += -I../../python
 | 
			
		||||
CPPFLAGS += -I../../imbuf
 | 
			
		||||
 | 
			
		||||
# own include 
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,6 @@ sources = env.Glob('*.c')
 | 
			
		||||
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
 | 
			
		||||
incs += ' ../../windowmanager #/intern/guardedalloc'
 | 
			
		||||
incs += ' #/intern/guardedalloc #intern/bmfont'
 | 
			
		||||
incs += ' ../../makesrna'
 | 
			
		||||
incs += ' ../../makesrna ../../python'
 | 
			
		||||
 | 
			
		||||
env.BlenderLib ( 'bf_editors_object', sources, Split(incs), [], libtype=['core'], priority=[35] )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										960
									
								
								source/blender/editors/object/editconstraint.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										960
									
								
								source/blender/editors/object/editconstraint.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,960 @@
 | 
			
		||||
/**
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2
 | 
			
		||||
 * of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The Original Code is: all of this file.
 | 
			
		||||
 *
 | 
			
		||||
 * Contributor(s): Joshua Leung, Blender Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * ***** END GPL LICENSE BLOCK *****
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "MEM_guardedalloc.h"
 | 
			
		||||
 | 
			
		||||
#include "BLI_blenlib.h"
 | 
			
		||||
#include "BLI_arithb.h"
 | 
			
		||||
#include "BLI_dynstr.h"
 | 
			
		||||
 | 
			
		||||
#include "DNA_action_types.h"
 | 
			
		||||
#include "DNA_armature_types.h"
 | 
			
		||||
#include "DNA_constraint_types.h"
 | 
			
		||||
#include "DNA_curve_types.h"
 | 
			
		||||
#include "DNA_object_types.h"
 | 
			
		||||
#include "DNA_scene_types.h"
 | 
			
		||||
#include "DNA_screen_types.h"
 | 
			
		||||
#include "DNA_text_types.h"
 | 
			
		||||
#include "DNA_view3d_types.h"
 | 
			
		||||
 | 
			
		||||
#include "BKE_action.h"
 | 
			
		||||
#include "BKE_armature.h"
 | 
			
		||||
#include "BKE_constraint.h"
 | 
			
		||||
#include "BKE_depsgraph.h"
 | 
			
		||||
#include "BKE_global.h"
 | 
			
		||||
#include "BKE_main.h"
 | 
			
		||||
#include "BKE_ipo.h"
 | 
			
		||||
#include "BKE_object.h"
 | 
			
		||||
#include "BKE_utildefines.h"
 | 
			
		||||
 | 
			
		||||
#ifndef DISABLE_PYTHON
 | 
			
		||||
#include "BPY_extern.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "ED_object.h"
 | 
			
		||||
 | 
			
		||||
#include "object_intern.h"
 | 
			
		||||
 | 
			
		||||
/* XXX */
 | 
			
		||||
static void BIF_undo_push() {}
 | 
			
		||||
static void error() {}
 | 
			
		||||
static int okee() {return 0;}
 | 
			
		||||
static int pupmenu() {return 0;}
 | 
			
		||||
 | 
			
		||||
/* -------------- Get Active Constraint Data ---------------------- */
 | 
			
		||||
 | 
			
		||||
ListBase *get_active_constraint_channels (Scene *scene, Object *ob, int forcevalid)
 | 
			
		||||
{
 | 
			
		||||
	char ipstr[64];
 | 
			
		||||
	
 | 
			
		||||
	if (ob == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	
 | 
			
		||||
	/* See if we are a bone constraint */
 | 
			
		||||
	if (ob->flag & OB_POSEMODE) {
 | 
			
		||||
		bActionChannel *achan;
 | 
			
		||||
		bPoseChannel *pchan;
 | 
			
		||||
		
 | 
			
		||||
		pchan = get_active_posechannel(ob);
 | 
			
		||||
		if (pchan) {
 | 
			
		||||
			/* Make sure we have an action */
 | 
			
		||||
			if (ob->action == NULL) {
 | 
			
		||||
				if (forcevalid == 0)
 | 
			
		||||
					return NULL;
 | 
			
		||||
				
 | 
			
		||||
				ob->action= add_empty_action("Action");
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			/* Make sure we have an actionchannel */
 | 
			
		||||
			achan = get_action_channel(ob->action, pchan->name);
 | 
			
		||||
			if (achan == NULL) {
 | 
			
		||||
				if (forcevalid == 0)
 | 
			
		||||
					return NULL;
 | 
			
		||||
				
 | 
			
		||||
				achan = MEM_callocN (sizeof(bActionChannel), "ActionChannel");
 | 
			
		||||
				
 | 
			
		||||
				strcpy(achan->name, pchan->name);
 | 
			
		||||
				sprintf(ipstr, "%s.%s", ob->action->id.name+2, achan->name);
 | 
			
		||||
				ipstr[23]=0;
 | 
			
		||||
				achan->ipo=	add_ipo(scene, ipstr, ID_AC);	
 | 
			
		||||
				
 | 
			
		||||
				BLI_addtail(&ob->action->chanbase, achan);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			return &achan->constraintChannels;
 | 
			
		||||
		}
 | 
			
		||||
		else 
 | 
			
		||||
			return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	/* else we return object constraints */
 | 
			
		||||
	else {
 | 
			
		||||
		if (ob->ipoflag & OB_ACTION_OB) {
 | 
			
		||||
			bActionChannel *achan = get_action_channel(ob->action, "Object");
 | 
			
		||||
			if (achan)
 | 
			
		||||
				return &achan->constraintChannels;
 | 
			
		||||
			else 
 | 
			
		||||
				return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return &ob->constraintChannels;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* if object in posemode, active bone constraints, else object constraints */
 | 
			
		||||
ListBase *get_active_constraints (Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	if (ob == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (ob->flag & OB_POSEMODE) {
 | 
			
		||||
		bPoseChannel *pchan;
 | 
			
		||||
		
 | 
			
		||||
		pchan = get_active_posechannel(ob);
 | 
			
		||||
		if (pchan)
 | 
			
		||||
			return &pchan->constraints;
 | 
			
		||||
	}
 | 
			
		||||
	else 
 | 
			
		||||
		return &ob->constraints;
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* single constraint */
 | 
			
		||||
bConstraint *get_active_constraint (Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	ListBase *lb= get_active_constraints(ob);
 | 
			
		||||
 | 
			
		||||
	if (lb) {
 | 
			
		||||
		bConstraint *con;
 | 
			
		||||
		
 | 
			
		||||
		for (con= lb->first; con; con=con->next) {
 | 
			
		||||
			if (con->flag & CONSTRAINT_ACTIVE)
 | 
			
		||||
				return con;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* single channel, for ipo */
 | 
			
		||||
bConstraintChannel *get_active_constraint_channel (Scene *scene, Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	bConstraint *con;
 | 
			
		||||
	bConstraintChannel *chan;
 | 
			
		||||
	
 | 
			
		||||
	if (ob->flag & OB_POSEMODE) {
 | 
			
		||||
		if (ob->action) {
 | 
			
		||||
			bPoseChannel *pchan;
 | 
			
		||||
			
 | 
			
		||||
			pchan = get_active_posechannel(ob);
 | 
			
		||||
			if (pchan) {
 | 
			
		||||
				for (con= pchan->constraints.first; con; con= con->next) {
 | 
			
		||||
					if (con->flag & CONSTRAINT_ACTIVE)
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				if (con) {
 | 
			
		||||
					bActionChannel *achan = get_action_channel(ob->action, pchan->name);
 | 
			
		||||
					if (achan) {
 | 
			
		||||
						for (chan= achan->constraintChannels.first; chan; chan= chan->next) {
 | 
			
		||||
							if (!strcmp(chan->name, con->name))
 | 
			
		||||
								break;
 | 
			
		||||
						}
 | 
			
		||||
						return chan;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		for (con= ob->constraints.first; con; con= con->next) {
 | 
			
		||||
			if (con->flag & CONSTRAINT_ACTIVE)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (con) {
 | 
			
		||||
			ListBase *lb= get_active_constraint_channels(scene, ob, 0);
 | 
			
		||||
			
 | 
			
		||||
			if (lb) {
 | 
			
		||||
				for (chan= lb->first; chan; chan= chan->next) {
 | 
			
		||||
					if (!strcmp(chan->name, con->name))
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				return chan;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
 | 
			
		||||
/* ------------- PyConstraints ------------------ */
 | 
			
		||||
 | 
			
		||||
/* this callback sets the text-file to be used for selected menu item */
 | 
			
		||||
void validate_pyconstraint_cb (void *arg1, void *arg2)
 | 
			
		||||
{
 | 
			
		||||
	bPythonConstraint *data = arg1;
 | 
			
		||||
	Text *text= NULL;
 | 
			
		||||
	int index = *((int *)arg2);
 | 
			
		||||
	int i;
 | 
			
		||||
	
 | 
			
		||||
	/* exception for no script */
 | 
			
		||||
	if (index) {
 | 
			
		||||
		/* innovative use of a for...loop to search */
 | 
			
		||||
		for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next);
 | 
			
		||||
	}
 | 
			
		||||
	data->text = text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef DISABLE_PYTHON
 | 
			
		||||
/* this returns a string for the list of usable pyconstraint script names */
 | 
			
		||||
char *buildmenu_pyconstraints (Text *con_text, int *pyconindex)
 | 
			
		||||
{
 | 
			
		||||
	DynStr *pupds= BLI_dynstr_new();
 | 
			
		||||
	Text *text;
 | 
			
		||||
	char *str;
 | 
			
		||||
	char buf[64];
 | 
			
		||||
	int i;
 | 
			
		||||
	
 | 
			
		||||
	/* add title first */
 | 
			
		||||
	sprintf(buf, "Scripts: %%t|[None]%%x0|");
 | 
			
		||||
	BLI_dynstr_append(pupds, buf);
 | 
			
		||||
	
 | 
			
		||||
	/* init active-index first */
 | 
			
		||||
	if (con_text == NULL)
 | 
			
		||||
		*pyconindex= 0;
 | 
			
		||||
	
 | 
			
		||||
	/* loop through markers, adding them */
 | 
			
		||||
	for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
 | 
			
		||||
		/* this is important to ensure that right script is shown as active */
 | 
			
		||||
		if (text == con_text) *pyconindex = i;
 | 
			
		||||
		
 | 
			
		||||
		/* only include valid pyconstraint scripts */
 | 
			
		||||
		if (BPY_is_pyconstraint(text)) {
 | 
			
		||||
			BLI_dynstr_append(pupds, text->id.name+2);
 | 
			
		||||
			
 | 
			
		||||
			sprintf(buf, "%%x%d", i);
 | 
			
		||||
			BLI_dynstr_append(pupds, buf);
 | 
			
		||||
			
 | 
			
		||||
			if (text->id.next)
 | 
			
		||||
				BLI_dynstr_append(pupds, "|");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* convert to normal MEM_malloc'd string */
 | 
			
		||||
	str= BLI_dynstr_get_cstring(pupds);
 | 
			
		||||
	BLI_dynstr_free(pupds);
 | 
			
		||||
	
 | 
			
		||||
	return str;
 | 
			
		||||
}
 | 
			
		||||
#endif /* DISABLE_PYTHON */
 | 
			
		||||
 | 
			
		||||
/* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
 | 
			
		||||
void update_pyconstraint_cb (void *arg1, void *arg2)
 | 
			
		||||
{
 | 
			
		||||
	Object *owner= (Object *)arg1;
 | 
			
		||||
	bConstraint *con= (bConstraint *)arg2;
 | 
			
		||||
#ifndef DISABLE_PYTHON
 | 
			
		||||
	if (owner && con)
 | 
			
		||||
		BPY_pyconstraint_update(owner, con);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Creates a new constraint, initialises its data, and returns it */
 | 
			
		||||
bConstraint *add_new_constraint (short type)
 | 
			
		||||
{
 | 
			
		||||
	bConstraint *con;
 | 
			
		||||
	bConstraintTypeInfo *cti;
 | 
			
		||||
 | 
			
		||||
	con = MEM_callocN(sizeof(bConstraint), "Constraint");
 | 
			
		||||
	
 | 
			
		||||
	/* Set up a generic constraint datablock */
 | 
			
		||||
	con->type = type;
 | 
			
		||||
	con->flag |= CONSTRAINT_EXPAND;
 | 
			
		||||
	con->enforce = 1.0F;
 | 
			
		||||
	strcpy(con->name, "Const");
 | 
			
		||||
	
 | 
			
		||||
	/* Load the data for it */
 | 
			
		||||
	cti = constraint_get_typeinfo(con);
 | 
			
		||||
	if (cti) {
 | 
			
		||||
		con->data = MEM_callocN(cti->size, cti->structName);
 | 
			
		||||
		
 | 
			
		||||
		/* only constraints that change any settings need this */
 | 
			
		||||
		if (cti->new_data)
 | 
			
		||||
			cti->new_data(con->data);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return con;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Adds the given constraint to the Object-level set of constraints for the given Object */
 | 
			
		||||
void add_constraint_to_object (bConstraint *con, Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	ListBase *list;
 | 
			
		||||
	list = &ob->constraints;
 | 
			
		||||
	
 | 
			
		||||
	if (list) {
 | 
			
		||||
		unique_constraint_name(con, list);
 | 
			
		||||
		BLI_addtail(list, con);
 | 
			
		||||
		
 | 
			
		||||
		if (proxylocked_constraints_owner(ob, NULL))
 | 
			
		||||
			con->flag |= CONSTRAINT_PROXY_LOCAL;
 | 
			
		||||
		
 | 
			
		||||
		con->flag |= CONSTRAINT_ACTIVE;
 | 
			
		||||
		for (con= con->prev; con; con= con->prev)
 | 
			
		||||
			con->flag &= ~CONSTRAINT_ACTIVE;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* helper function for add_constriant - sets the last target for the active constraint */
 | 
			
		||||
static void set_constraint_nth_target (bConstraint *con, Object *target, char subtarget[], int index)
 | 
			
		||||
{
 | 
			
		||||
	bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
 | 
			
		||||
	ListBase targets = {NULL, NULL};
 | 
			
		||||
	bConstraintTarget *ct;
 | 
			
		||||
	int num_targets, i;
 | 
			
		||||
	
 | 
			
		||||
	if (cti && cti->get_constraint_targets) {
 | 
			
		||||
		cti->get_constraint_targets(con, &targets);
 | 
			
		||||
		num_targets= BLI_countlist(&targets);
 | 
			
		||||
		
 | 
			
		||||
		if (index < 0) {
 | 
			
		||||
			if (abs(index) < num_targets)
 | 
			
		||||
				index= num_targets - abs(index);
 | 
			
		||||
			else
 | 
			
		||||
				index= num_targets - 1;
 | 
			
		||||
		}
 | 
			
		||||
		else if (index >= num_targets) {
 | 
			
		||||
			index= num_targets - 1;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		for (ct=targets.first, i=0; ct; ct= ct->next, i++) {
 | 
			
		||||
			if (i == index) {
 | 
			
		||||
				ct->tar= target;
 | 
			
		||||
				strcpy(ct->subtarget, subtarget);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (cti->flush_constraint_targets)
 | 
			
		||||
			cti->flush_constraint_targets(con, &targets, 0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* context: active object in posemode, active channel, optional selected channel */
 | 
			
		||||
void add_constraint (Scene *scene, View3D *v3d, short only_IK)
 | 
			
		||||
{
 | 
			
		||||
	Object *ob= OBACT, *obsel=NULL;
 | 
			
		||||
	bPoseChannel *pchanact=NULL, *pchansel=NULL;
 | 
			
		||||
	bConstraint *con=NULL;
 | 
			
		||||
	Base *base;
 | 
			
		||||
	short nr;
 | 
			
		||||
	
 | 
			
		||||
	/* paranoia checks */
 | 
			
		||||
	if ((ob==NULL) || (ob==scene->obedit)) 
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
 | 
			
		||||
		bArmature *arm= ob->data;
 | 
			
		||||
		
 | 
			
		||||
		/* find active channel */
 | 
			
		||||
		pchanact= get_active_posechannel(ob);
 | 
			
		||||
		if (pchanact==NULL) 
 | 
			
		||||
			return;
 | 
			
		||||
		
 | 
			
		||||
		/* find selected bone */
 | 
			
		||||
		for (pchansel=ob->pose->chanbase.first; pchansel; pchansel=pchansel->next) {
 | 
			
		||||
			if (pchansel != pchanact) {
 | 
			
		||||
				if (pchansel->bone->flag & BONE_SELECTED)  {
 | 
			
		||||
					if (pchansel->bone->layer & arm->layer)
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* find selected object */
 | 
			
		||||
	for (base= FIRSTBASE; base; base= base->next) {
 | 
			
		||||
		if ((TESTBASE(v3d, base)) && (base->object!=ob)) 
 | 
			
		||||
			obsel= base->object;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* the only_IK caller has checked for posemode! */
 | 
			
		||||
	if (only_IK) {
 | 
			
		||||
		for (con= pchanact->constraints.first; con; con= con->next) {
 | 
			
		||||
			if (con->type==CONSTRAINT_TYPE_KINEMATIC) break;
 | 
			
		||||
		}
 | 
			
		||||
		if (con) {
 | 
			
		||||
			error("Pose Channel already has IK");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (pchansel)
 | 
			
		||||
			nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
 | 
			
		||||
		else if (obsel)
 | 
			
		||||
			nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
 | 
			
		||||
		else 
 | 
			
		||||
			nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		if (pchanact) {
 | 
			
		||||
			if (pchansel)
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
			else if ((obsel) && (obsel->type==OB_CURVE))
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
			else if (obsel)
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
			else
 | 
			
		||||
				nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if ((obsel) && (obsel->type==OB_CURVE))
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18");
 | 
			
		||||
			else if (obsel)
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
 | 
			
		||||
			else
 | 
			
		||||
				nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (nr < 1) return;
 | 
			
		||||
	
 | 
			
		||||
	/* handle IK separate */
 | 
			
		||||
	if (nr==10 || nr==11) {
 | 
			
		||||
		/* ik - prevent weird chains... */
 | 
			
		||||
		if (pchansel) {
 | 
			
		||||
			bPoseChannel *pchan= pchanact;
 | 
			
		||||
			while (pchan) {
 | 
			
		||||
				if (pchan==pchansel) break;
 | 
			
		||||
				pchan= pchan->parent;
 | 
			
		||||
			}
 | 
			
		||||
			if (pchan) {
 | 
			
		||||
				error("IK root cannot be linked to IK tip");
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			pchan= pchansel;
 | 
			
		||||
			while (pchan) {
 | 
			
		||||
				if (pchan==pchanact) break;
 | 
			
		||||
				pchan= pchan->parent;
 | 
			
		||||
			}
 | 
			
		||||
			if (pchan) {
 | 
			
		||||
				error("IK tip cannot be linked to IK root");
 | 
			
		||||
				return;
 | 
			
		||||
			}		
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
 | 
			
		||||
		BLI_addtail(&pchanact->constraints, con);
 | 
			
		||||
		unique_constraint_name(con, &pchanact->constraints);
 | 
			
		||||
		pchanact->constflag |= PCHAN_HAS_IK;	/* for draw, but also for detecting while pose solving */
 | 
			
		||||
		if (nr==11) 
 | 
			
		||||
			pchanact->constflag |= PCHAN_HAS_TARGET;
 | 
			
		||||
		if (proxylocked_constraints_owner(ob, pchanact))
 | 
			
		||||
			con->flag |= CONSTRAINT_PROXY_LOCAL;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		/* normal constraints - add data */
 | 
			
		||||
		if (nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
 | 
			
		||||
		else if (nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
 | 
			
		||||
		else if (nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
 | 
			
		||||
		else if (nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
 | 
			
		||||
		else if (nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
 | 
			
		||||
		else if (nr==6) {
 | 
			
		||||
			Curve *cu= obsel->data;
 | 
			
		||||
			cu->flag |= CU_PATH;
 | 
			
		||||
			con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
 | 
			
		||||
		}
 | 
			
		||||
		else if (nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
 | 
			
		||||
		else if (nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
 | 
			
		||||
		else if (nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
 | 
			
		||||
		else if (nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
 | 
			
		||||
		else if (nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
 | 
			
		||||
		else if (nr==16) {
 | 
			
		||||
			/* TODO: add a popup-menu to display list of available actions to use (like for pyconstraints) */
 | 
			
		||||
			con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
 | 
			
		||||
		}
 | 
			
		||||
		else if (nr==17) {
 | 
			
		||||
			Curve *cu= obsel->data;
 | 
			
		||||
			cu->flag |= CU_PATH;
 | 
			
		||||
			con = add_new_constraint(CONSTRAINT_TYPE_CLAMPTO);
 | 
			
		||||
		}
 | 
			
		||||
		else if (nr==18) {	
 | 
			
		||||
			char *menustr;
 | 
			
		||||
			int scriptint= 0;
 | 
			
		||||
#ifndef DISABLE_PYTHON
 | 
			
		||||
			/* popup a list of usable scripts */
 | 
			
		||||
			menustr = buildmenu_pyconstraints(NULL, &scriptint);
 | 
			
		||||
			scriptint = pupmenu(menustr);
 | 
			
		||||
			MEM_freeN(menustr);
 | 
			
		||||
			
 | 
			
		||||
			/* only add constraint if a script was chosen */
 | 
			
		||||
			if (scriptint) {
 | 
			
		||||
				/* add constraint */
 | 
			
		||||
				con = add_new_constraint(CONSTRAINT_TYPE_PYTHON);
 | 
			
		||||
				validate_pyconstraint_cb(con->data, &scriptint);
 | 
			
		||||
				
 | 
			
		||||
				/* make sure target allowance is set correctly */
 | 
			
		||||
				BPY_pyconstraint_update(ob, con);
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
		else if (nr==19) {
 | 
			
		||||
			con = add_new_constraint(CONSTRAINT_TYPE_CHILDOF);
 | 
			
		||||
		
 | 
			
		||||
			/* if this constraint is being added to a posechannel, make sure
 | 
			
		||||
			 * the constraint gets evaluated in pose-space
 | 
			
		||||
			 */
 | 
			
		||||
			if (pchanact) {
 | 
			
		||||
				con->ownspace = CONSTRAINT_SPACE_POSE;
 | 
			
		||||
				con->flag |= CONSTRAINT_SPACEONCE;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (nr==20) con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
 | 
			
		||||
		else if (nr==21) con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
 | 
			
		||||
		
 | 
			
		||||
		if (con==NULL) return;	/* paranoia */
 | 
			
		||||
		
 | 
			
		||||
		if (pchanact) {
 | 
			
		||||
			BLI_addtail(&pchanact->constraints, con);
 | 
			
		||||
			unique_constraint_name(con, &pchanact->constraints);
 | 
			
		||||
			pchanact->constflag |= PCHAN_HAS_CONST;	/* for draw */
 | 
			
		||||
			if (proxylocked_constraints_owner(ob, pchanact))
 | 
			
		||||
				con->flag |= CONSTRAINT_PROXY_LOCAL;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			BLI_addtail(&ob->constraints, con);
 | 
			
		||||
			unique_constraint_name(con, &ob->constraints);
 | 
			
		||||
			if (proxylocked_constraints_owner(ob, NULL))
 | 
			
		||||
				con->flag |= CONSTRAINT_PROXY_LOCAL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* set the target */
 | 
			
		||||
	if (pchansel) {
 | 
			
		||||
		set_constraint_nth_target(con, ob, pchansel->name, 0);
 | 
			
		||||
	}
 | 
			
		||||
	else if (obsel) {
 | 
			
		||||
		set_constraint_nth_target(con, obsel, "", 0);
 | 
			
		||||
	}
 | 
			
		||||
	else if (ELEM4(nr, 11, 13, 14, 15)==0) {	/* add new empty as target */
 | 
			
		||||
		Base *base= BASACT, *newbase;
 | 
			
		||||
		Object *obt;
 | 
			
		||||
		
 | 
			
		||||
		obt= add_object(scene, OB_EMPTY);
 | 
			
		||||
		/* set layers OK */
 | 
			
		||||
		newbase= BASACT;
 | 
			
		||||
		newbase->lay= base->lay;
 | 
			
		||||
		obt->lay= newbase->lay;
 | 
			
		||||
		
 | 
			
		||||
		/* transform cent to global coords for loc */
 | 
			
		||||
		if (pchanact) {
 | 
			
		||||
			if (only_IK)
 | 
			
		||||
				VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
 | 
			
		||||
			else
 | 
			
		||||
				VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			VECCOPY(obt->loc, ob->obmat[3]);
 | 
			
		||||
		
 | 
			
		||||
		set_constraint_nth_target(con, obt, "", 0);
 | 
			
		||||
		
 | 
			
		||||
		/* restore, add_object sets active */
 | 
			
		||||
		BASACT= base;
 | 
			
		||||
		base->flag |= SELECT;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* active flag */
 | 
			
		||||
	con->flag |= CONSTRAINT_ACTIVE;
 | 
			
		||||
	for (con= con->prev; con; con= con->prev)
 | 
			
		||||
		con->flag &= ~CONSTRAINT_ACTIVE;
 | 
			
		||||
 | 
			
		||||
	DAG_scene_sort(scene);		// sort order of objects
 | 
			
		||||
	
 | 
			
		||||
	if (pchanact) {
 | 
			
		||||
		ob->pose->flag |= POSE_RECALC;	// sort pose channels
 | 
			
		||||
		DAG_object_flush_update(scene, ob, OB_RECALC_DATA);	// and all its relations
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		DAG_object_flush_update(scene, ob, OB_RECALC_OB);	// and all its relations
 | 
			
		||||
 | 
			
		||||
	if (only_IK)
 | 
			
		||||
		BIF_undo_push("Add IK Constraint");
 | 
			
		||||
	else
 | 
			
		||||
		BIF_undo_push("Add Constraint");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Remove all constraints from the active object */
 | 
			
		||||
void ob_clear_constraints (Scene *scene)
 | 
			
		||||
{
 | 
			
		||||
	Object *ob= OBACT;
 | 
			
		||||
	
 | 
			
		||||
	/* paranoia checks */
 | 
			
		||||
	if ((ob==NULL) || (ob==scene->obedit) || (ob->flag & OB_POSEMODE)) 
 | 
			
		||||
		return;
 | 
			
		||||
	
 | 
			
		||||
	/* get user permission */
 | 
			
		||||
	if (okee("Clear Constraints")==0) 
 | 
			
		||||
		return;
 | 
			
		||||
	
 | 
			
		||||
	/* do freeing */
 | 
			
		||||
	free_constraints(&ob->constraints);
 | 
			
		||||
	
 | 
			
		||||
	/* do updates */
 | 
			
		||||
	DAG_object_flush_update(scene, ob, OB_RECALC_OB);
 | 
			
		||||
	
 | 
			
		||||
	BIF_undo_push("Clear Constraint(s)");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Rename the given constraint 
 | 
			
		||||
 *	- con already has the new name 
 | 
			
		||||
 */
 | 
			
		||||
void rename_constraint (Object *ob, bConstraint *con, char *oldname)
 | 
			
		||||
{
 | 
			
		||||
	bConstraint *tcon;
 | 
			
		||||
	bConstraintChannel *conchan;
 | 
			
		||||
	ListBase *conlist= NULL;
 | 
			
		||||
	int from_object= 0;
 | 
			
		||||
	char *channame="";
 | 
			
		||||
	
 | 
			
		||||
	/* get context by searching for con (primitive...) */
 | 
			
		||||
	for (tcon= ob->constraints.first; tcon; tcon= tcon->next) {
 | 
			
		||||
		if (tcon==con)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (tcon) {
 | 
			
		||||
		conlist= &ob->constraints;
 | 
			
		||||
		channame= "Object";
 | 
			
		||||
		from_object= 1;
 | 
			
		||||
	}
 | 
			
		||||
	else if (ob->pose) {
 | 
			
		||||
		bPoseChannel *pchan;
 | 
			
		||||
		
 | 
			
		||||
		for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
 | 
			
		||||
			for (tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
 | 
			
		||||
				if (tcon==con)
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			if (tcon) 
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (tcon) {
 | 
			
		||||
			conlist= &pchan->constraints;
 | 
			
		||||
			channame= pchan->name;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (conlist==NULL) {
 | 
			
		||||
		printf("rename constraint failed\n");	/* should not happen in UI */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* first make sure it's a unique name within context */
 | 
			
		||||
	unique_constraint_name (con, conlist);
 | 
			
		||||
 | 
			
		||||
	/* own channels */
 | 
			
		||||
	if (from_object) {
 | 
			
		||||
		for (conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
 | 
			
		||||
			if ( strcmp(oldname, conchan->name)==0 )
 | 
			
		||||
				BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* own action */
 | 
			
		||||
	if (ob->action) {
 | 
			
		||||
		bActionChannel *achan= get_action_channel(ob->action, channame);
 | 
			
		||||
		if (achan) {
 | 
			
		||||
			conchan= get_constraint_channel(&achan->constraintChannels, oldname);
 | 
			
		||||
			if (conchan)
 | 
			
		||||
				BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ------------- Constraint Sanity Testing ------------------- */
 | 
			
		||||
 | 
			
		||||
/* 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
 | 
			
		||||
				 */
 | 
			
		||||
				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;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				/* 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);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_bonelist_constraints (Object *owner, ListBase *list)
 | 
			
		||||
{
 | 
			
		||||
	Bone *bone;
 | 
			
		||||
 | 
			
		||||
	for (bone = list->first; bone; bone = bone->next) {
 | 
			
		||||
		test_constraints(owner, bone->name);
 | 
			
		||||
		test_bonelist_constraints(owner, &bone->childbase);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void object_test_constraints (Object *owner)
 | 
			
		||||
{
 | 
			
		||||
	test_constraints(owner, "");
 | 
			
		||||
 | 
			
		||||
	if (owner->type==OB_ARMATURE) {
 | 
			
		||||
		bArmature *arm= get_armature(owner);
 | 
			
		||||
		
 | 
			
		||||
		if (arm)
 | 
			
		||||
			test_bonelist_constraints(owner, &arm->bonebase);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
 | 
			
		||||
 | 
			
		||||
/* ------------- Child-Of Constraint ------------------ */
 | 
			
		||||
 | 
			
		||||
/* ChildOf Constraint - set inverse callback */
 | 
			
		||||
void childof_const_setinv (void *conv, void *scenev)
 | 
			
		||||
{
 | 
			
		||||
	bConstraint *con= (bConstraint *)conv;
 | 
			
		||||
	Scene *scene= (Scene *)scenev;
 | 
			
		||||
	bChildOfConstraint *data= (bChildOfConstraint *)con->data;
 | 
			
		||||
	Object *ob= OBACT;
 | 
			
		||||
	bPoseChannel *pchan= NULL;
 | 
			
		||||
 | 
			
		||||
	/* try to find a pose channel */
 | 
			
		||||
	if (ob && ob->pose)
 | 
			
		||||
		pchan= get_active_posechannel(ob);
 | 
			
		||||
	
 | 
			
		||||
	/* calculate/set inverse matrix */
 | 
			
		||||
	if (pchan) {
 | 
			
		||||
		float pmat[4][4], cinf;
 | 
			
		||||
		float imat[4][4], tmat[4][4];
 | 
			
		||||
		
 | 
			
		||||
		/* make copy of pchan's original pose-mat (for use later) */
 | 
			
		||||
		Mat4CpyMat4(pmat, pchan->pose_mat);
 | 
			
		||||
		
 | 
			
		||||
		/* disable constraint for pose to be solved without it */
 | 
			
		||||
		cinf= con->enforce;
 | 
			
		||||
		con->enforce= 0.0f;
 | 
			
		||||
		
 | 
			
		||||
		/* solve pose without constraint */
 | 
			
		||||
		where_is_pose(scene, ob);
 | 
			
		||||
		
 | 
			
		||||
		/* determine effect of constraint by removing the newly calculated 
 | 
			
		||||
		 * pchan->pose_mat from the original pchan->pose_mat, thus determining 
 | 
			
		||||
		 * the effect of the constraint
 | 
			
		||||
		 */
 | 
			
		||||
		Mat4Invert(imat, pchan->pose_mat);
 | 
			
		||||
		Mat4MulMat4(tmat, imat, pmat);
 | 
			
		||||
		Mat4Invert(data->invmat, tmat);
 | 
			
		||||
		
 | 
			
		||||
		/* recalculate pose with new inv-mat */
 | 
			
		||||
		con->enforce= cinf;
 | 
			
		||||
		where_is_pose(scene, ob);
 | 
			
		||||
	}
 | 
			
		||||
	else if (ob) {
 | 
			
		||||
		Object workob;
 | 
			
		||||
		/* use what_does_parent to find inverse - just like for normal parenting.
 | 
			
		||||
		 * NOTE: what_does_parent uses a static workob defined in object.c 
 | 
			
		||||
		 */
 | 
			
		||||
		what_does_parent(scene, ob, &workob);
 | 
			
		||||
		Mat4Invert(data->invmat, workob.obmat);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		Mat4One(data->invmat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ChildOf Constraint - clear inverse callback */
 | 
			
		||||
void childof_const_clearinv (void *conv, void *unused)
 | 
			
		||||
{
 | 
			
		||||
	bConstraint *con= (bConstraint *)conv;
 | 
			
		||||
	bChildOfConstraint *data= (bChildOfConstraint *)con->data;
 | 
			
		||||
	
 | 
			
		||||
	/* simply clear the matrix */
 | 
			
		||||
	Mat4One(data->invmat);
 | 
			
		||||
}
 | 
			
		||||
@@ -143,7 +143,6 @@ static void waitcursor() {}
 | 
			
		||||
static int pupmenu() {return 0;}
 | 
			
		||||
static int pupmenu_col() {return 0;}
 | 
			
		||||
static int okee() {return 0;}
 | 
			
		||||
static void EM_select_flush() {}
 | 
			
		||||
 | 
			
		||||
/* port over here */
 | 
			
		||||
static bContext *C;
 | 
			
		||||
@@ -465,7 +464,7 @@ static void select_editmesh_hook(Object *ob, HookModifierData *hmd)
 | 
			
		||||
			if(index < hmd->totindex-1) index++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	EM_select_flush();
 | 
			
		||||
	EM_select_flush(em);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int return_editlattice_indexar(int *tot, int **indexar, float *cent)
 | 
			
		||||
@@ -909,9 +908,9 @@ void make_track(Scene *scene, View3D *v3d, short mode)
 | 
			
		||||
	/*short mode=0;*/
 | 
			
		||||
	
 | 
			
		||||
	if(scene->id.lib) return;
 | 
			
		||||
// XXX	if(obedit) {
 | 
			
		||||
//		return; 
 | 
			
		||||
//	}
 | 
			
		||||
	if(scene->obedit) {
 | 
			
		||||
		return; 
 | 
			
		||||
	}
 | 
			
		||||
	if(BASACT==0) return;
 | 
			
		||||
 | 
			
		||||
	mode= pupmenu("Make Track %t|TrackTo Constraint %x1|LockTrack Constraint %x2|Old Track %x3");
 | 
			
		||||
@@ -925,7 +924,7 @@ void make_track(Scene *scene, View3D *v3d, short mode)
 | 
			
		||||
		for(base= FIRSTBASE; base; base= base->next) {
 | 
			
		||||
			if(TESTBASELIB(v3d, base)) {
 | 
			
		||||
				if(base!=BASACT) {
 | 
			
		||||
// XXX					con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
 | 
			
		||||
					con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
 | 
			
		||||
					strcpy (con->name, "AutoTrack");
 | 
			
		||||
 | 
			
		||||
					data = con->data;
 | 
			
		||||
@@ -938,7 +937,7 @@ void make_track(Scene *scene, View3D *v3d, short mode)
 | 
			
		||||
						data->reserved2 = UP_Y;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
// XXX					add_constraint_to_object(con, base->object);
 | 
			
		||||
					add_constraint_to_object(con, base->object);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -951,7 +950,7 @@ void make_track(Scene *scene, View3D *v3d, short mode)
 | 
			
		||||
		for(base= FIRSTBASE; base; base= base->next) {
 | 
			
		||||
			if(TESTBASELIB(v3d, base)) {
 | 
			
		||||
				if(base!=BASACT) {
 | 
			
		||||
// XXX					con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
 | 
			
		||||
					con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
 | 
			
		||||
					strcpy (con->name, "AutoTrack");
 | 
			
		||||
 | 
			
		||||
					data = con->data;
 | 
			
		||||
@@ -964,7 +963,7 @@ void make_track(Scene *scene, View3D *v3d, short mode)
 | 
			
		||||
						data->lockflag = LOCK_Y;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
// XXX					add_constraint_to_object(con, base->object);
 | 
			
		||||
					add_constraint_to_object(con, base->object);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -1317,7 +1316,7 @@ static int object_clear_location_exec(bContext *C, wmOperator *op)
 | 
			
		||||
			 *	- with clearing transform of object being edited at the time
 | 
			
		||||
			 */
 | 
			
		||||
			if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
 | 
			
		||||
// XXX				clear_armature(ob, mode);
 | 
			
		||||
				clear_armature(scene, ob, 'g');
 | 
			
		||||
				armature_clear= 1;	/* silly system to prevent another dag update, so no action applied */
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -1368,7 +1367,7 @@ static int object_clear_rotation_exec(bContext *C, wmOperator *op)
 | 
			
		||||
			 *	- with clearing transform of object being edited at the time
 | 
			
		||||
			 */
 | 
			
		||||
			if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
 | 
			
		||||
// XXX				clear_armature(ob, mode);
 | 
			
		||||
				clear_armature(scene, ob, 'r');
 | 
			
		||||
				armature_clear= 1;	/* silly system to prevent another dag update, so no action applied */
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -1420,7 +1419,7 @@ static int object_clear_scale_exec(bContext *C, wmOperator *op)
 | 
			
		||||
			 *	- with clearing transform of object being edited at the time
 | 
			
		||||
			 */
 | 
			
		||||
			if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
 | 
			
		||||
// XXX				clear_armature(ob, mode);
 | 
			
		||||
				clear_armature(scene, ob, 's');
 | 
			
		||||
				armature_clear= 1;	/* silly system to prevent another dag update, so no action applied */
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -1466,22 +1465,10 @@ void OBJECT_OT_clear_scale(wmOperatorType *ot)
 | 
			
		||||
 | 
			
		||||
static int object_clear_origin_exec(bContext *C, wmOperator *op)
 | 
			
		||||
{
 | 
			
		||||
	Scene *scene= CTX_data_scene(C);
 | 
			
		||||
	float *v1, *v3, mat[3][3];
 | 
			
		||||
	int armature_clear= 0;
 | 
			
		||||
 | 
			
		||||
	CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
 | 
			
		||||
		if ((ob->flag & OB_POSEMODE)) {
 | 
			
		||||
			/* only clear pose transforms if:
 | 
			
		||||
			 *	- with a mesh in weightpaint mode, it's related armature needs to be cleared
 | 
			
		||||
			 *	- with clearing transform of object being edited at the time
 | 
			
		||||
			 */
 | 
			
		||||
			if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
 | 
			
		||||
// XXX				clear_armature(ob, mode);
 | 
			
		||||
				armature_clear= 1;	/* silly system to prevent another dag update, so no action applied */
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if((G.f & G_WEIGHTPAINT)==0) {
 | 
			
		||||
		if(ob->parent) {
 | 
			
		||||
			v1= ob->loc;
 | 
			
		||||
			v3= ob->parentinv[3];
 | 
			
		||||
@@ -1493,7 +1480,6 @@ static int object_clear_origin_exec(bContext *C, wmOperator *op)
 | 
			
		||||
			v3[2]= -v3[2];
 | 
			
		||||
			Mat3MulVecfl(mat, v3);
 | 
			
		||||
		}
 | 
			
		||||
		}
 | 
			
		||||
		ob->recalc |= OB_RECALC_OB;
 | 
			
		||||
	}
 | 
			
		||||
	CTX_DATA_END;
 | 
			
		||||
@@ -1929,49 +1915,6 @@ void make_proxy(Scene *scene)
 | 
			
		||||
#if 0
 | 
			
		||||
oldcode()
 | 
			
		||||
{
 | 
			
		||||
	else if(mode==4) {
 | 
			
		||||
		bConstraint *con;
 | 
			
		||||
		bFollowPathConstraint *data;
 | 
			
		||||
			
 | 
			
		||||
		for(base= FIRSTBASE; base; base= base->next) {
 | 
			
		||||
			if(TESTBASELIB(v3d, base)) {
 | 
			
		||||
				if(base!=BASACT) {
 | 
			
		||||
					float cmat[4][4], vec[3];
 | 
			
		||||
					
 | 
			
		||||
// XXX						con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
 | 
			
		||||
					strcpy (con->name, "AutoPath");
 | 
			
		||||
					
 | 
			
		||||
					data = con->data;
 | 
			
		||||
					data->tar = BASACT->object;
 | 
			
		||||
					
 | 
			
		||||
// XXX						add_constraint_to_object(con, base->object);
 | 
			
		||||
					
 | 
			
		||||
					get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(base->object));
 | 
			
		||||
					VecSubf(vec, base->object->obmat[3], cmat[3]);
 | 
			
		||||
					
 | 
			
		||||
					base->object->loc[0] = vec[0];
 | 
			
		||||
					base->object->loc[1] = vec[1];
 | 
			
		||||
					base->object->loc[2] = vec[2];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(mode==PARSKEL && base->object->type==OB_MESH && par->type == OB_ARMATURE) {
 | 
			
		||||
			/* Prompt the user as to whether he wants to
 | 
			
		||||
				* add some vertex groups based on the bones
 | 
			
		||||
				* in the parent armature.
 | 
			
		||||
				*/
 | 
			
		||||
// XXX							create_vgroups_from_armature(base->object, par);
 | 
			
		||||
 | 
			
		||||
			base->object->partype= PAROBJECT;
 | 
			
		||||
			what_does_parent(scene, base->object);
 | 
			
		||||
			Mat4One (base->object->parentinv);
 | 
			
		||||
			base->object->partype= mode;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			what_does_parent(scene, base->object, &workob);
 | 
			
		||||
		Mat4Invert(base->object->parentinv, workob.obmat);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -2066,13 +2009,51 @@ static int make_parent_exec(bContext *C, wmOperator *op)
 | 
			
		||||
				else
 | 
			
		||||
					ob->parsubstr[0]= 0;
 | 
			
		||||
				
 | 
			
		||||
				/* constraint XXX */
 | 
			
		||||
				/* constraint */
 | 
			
		||||
				if(partype==PAR_PATH_CONST) {
 | 
			
		||||
				}
 | 
			
		||||
					bConstraint *con;
 | 
			
		||||
					bFollowPathConstraint *data;
 | 
			
		||||
					float cmat[4][4], vec[3];
 | 
			
		||||
					
 | 
			
		||||
					con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
 | 
			
		||||
					strcpy (con->name, "AutoPath");
 | 
			
		||||
					
 | 
			
		||||
					data = con->data;
 | 
			
		||||
					data->tar = par;
 | 
			
		||||
					
 | 
			
		||||
					add_constraint_to_object(con, ob);
 | 
			
		||||
					
 | 
			
		||||
					get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob));
 | 
			
		||||
					VecSubf(vec, ob->obmat[3], cmat[3]);
 | 
			
		||||
					
 | 
			
		||||
					ob->loc[0] = vec[0];
 | 
			
		||||
					ob->loc[1] = vec[1];
 | 
			
		||||
				}
 | 
			
		||||
				else if(partype==PAR_ARMATURE && ob->type==OB_MESH && par->type == OB_ARMATURE) {
 | 
			
		||||
					
 | 
			
		||||
					if(1) {
 | 
			
		||||
						/* Prompt the user as to whether he wants to
 | 
			
		||||
						* add some vertex groups based on the bones
 | 
			
		||||
						* in the parent armature.
 | 
			
		||||
						*/
 | 
			
		||||
						create_vgroups_from_armature(scene, ob, par);
 | 
			
		||||
						
 | 
			
		||||
						/* get corrected inverse */
 | 
			
		||||
						ob->partype= PAROBJECT;
 | 
			
		||||
						what_does_parent(scene, ob, &workob);
 | 
			
		||||
						
 | 
			
		||||
						ob->partype= PARSKEL;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
						what_does_parent(scene, ob, &workob);
 | 
			
		||||
					
 | 
			
		||||
					Mat4Invert(ob->parentinv, workob.obmat);
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					/* calculate inverse parent matrix */
 | 
			
		||||
					what_does_parent(scene, ob, &workob);
 | 
			
		||||
					Mat4Invert(ob->parentinv, workob.obmat);
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
 | 
			
		||||
				
 | 
			
		||||
@@ -2169,7 +2150,7 @@ static int make_track_exec(bContext *C, wmOperator *op)
 | 
			
		||||
		for(base= FIRSTBASE; base; base= base->next) {
 | 
			
		||||
			if(TESTBASELIB(v3d, base)) {
 | 
			
		||||
				if(base!=BASACT) {
 | 
			
		||||
// XXX					con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
 | 
			
		||||
					con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
 | 
			
		||||
					strcpy (con->name, "AutoTrack");
 | 
			
		||||
 | 
			
		||||
					data = con->data;
 | 
			
		||||
@@ -2182,7 +2163,7 @@ static int make_track_exec(bContext *C, wmOperator *op)
 | 
			
		||||
						data->reserved2 = UP_Y;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
// XXX					add_constraint_to_object(con, base->object);
 | 
			
		||||
					add_constraint_to_object(con, base->object);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -2195,7 +2176,7 @@ static int make_track_exec(bContext *C, wmOperator *op)
 | 
			
		||||
		for(base= FIRSTBASE; base; base= base->next) {
 | 
			
		||||
			if(TESTBASELIB(v3d, base)) {
 | 
			
		||||
				if(base!=BASACT) {
 | 
			
		||||
// XXX					con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
 | 
			
		||||
					con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
 | 
			
		||||
					strcpy (con->name, "AutoTrack");
 | 
			
		||||
 | 
			
		||||
					data = con->data;
 | 
			
		||||
@@ -2208,7 +2189,7 @@ static int make_track_exec(bContext *C, wmOperator *op)
 | 
			
		||||
						data->lockflag = LOCK_Y;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
// XXX					add_constraint_to_object(con, base->object);
 | 
			
		||||
					add_constraint_to_object(con, base->object);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -2508,7 +2489,7 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
 | 
			
		||||
				VecSubf(eve->co, eve->co, cent);			
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
// XXX			recalc_editnormals();
 | 
			
		||||
			recalc_editnormals(me->edit_mesh);
 | 
			
		||||
			tot_change++;
 | 
			
		||||
			DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
 | 
			
		||||
		}
 | 
			
		||||
@@ -2743,7 +2724,7 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
 | 
			
		||||
						/* Function to recenter armatures in editarmature.c 
 | 
			
		||||
						 * Bone + object locations are handled there.
 | 
			
		||||
						 */
 | 
			
		||||
// XXX						docenter_armature(base->object, centermode);
 | 
			
		||||
						docenter_armature(scene, v3d, base->object, centermode);
 | 
			
		||||
						tot_change++;
 | 
			
		||||
						
 | 
			
		||||
						where_is_object(scene, base->object);
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,8 @@
 | 
			
		||||
#ifndef ED_OBJECT_INTERN_H
 | 
			
		||||
#define ED_OBJECT_INTERN_H
 | 
			
		||||
 | 
			
		||||
struct wmOperatorType;
 | 
			
		||||
 | 
			
		||||
/* internal exports only */
 | 
			
		||||
#define CLEAR_OBJ_ROTATION 0
 | 
			
		||||
#define CLEAR_OBJ_LOCATION 1
 | 
			
		||||
@@ -35,24 +37,24 @@
 | 
			
		||||
#define CLEAR_OBJ_ORIGIN 3
 | 
			
		||||
 | 
			
		||||
/* object_edit.c */
 | 
			
		||||
void OBJECT_OT_toggle_editmode(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_make_parent(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_parent(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_make_track(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_track(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_de_select_all(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_select_invert(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_select_random(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_select_by_type(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_select_by_layer(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_location(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_rotation(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_scale(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_origin(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_restrictview(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_set_restrictview(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_set_slowparent(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_slowparent(wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_toggle_editmode(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_make_parent(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_parent(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_make_track(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_track(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_de_select_all(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_select_invert(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_select_random(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_select_by_type(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_select_by_layer(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_location(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_rotation(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_scale(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_origin(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_restrictview(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_set_restrictview(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_set_slowparent(struct wmOperatorType *ot);
 | 
			
		||||
void OBJECT_OT_clear_slowparent(struct wmOperatorType *ot);
 | 
			
		||||
 | 
			
		||||
#endif /* ED_OBJECT_INTERN_H */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -39,4 +39,5 @@ void BPY_clear_script() {}
 | 
			
		||||
void BPY_free_compiled_text() {}
 | 
			
		||||
void BPY_pyconstraint_eval() {}
 | 
			
		||||
void BPY_pyconstraint_target() {}
 | 
			
		||||
 | 
			
		||||
int BPY_is_pyconstraint() {return 0;}
 | 
			
		||||
void BPY_pyconstraint_update() {}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user