diff options
author | Ton Roosendaal <ton@blender.org> | 2009-01-10 22:34:23 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-01-10 22:34:23 +0300 |
commit | 1beef956ca96c76e3ee7d6ba80d0c88e2b92b258 (patch) | |
tree | c6c52bf29ac8ef8278d4061761a6e91f1b0f4c88 /source | |
parent | 3c2b772a23728361b060a406528f6f2a422a278f (diff) |
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)
Diffstat (limited to 'source')
21 files changed, 1141 insertions, 169 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 409b1a7a44a..0595134f5c9 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -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); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 40120e2b61a..5c11a564527 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -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); diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index cce085f3077..8ef3ff4d4b7 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -58,7 +58,7 @@ /* Structs */ struct Object; -struct Scene *scene; +struct Scene; struct SoftBody; struct ParticleSystem; struct ClothModifierData; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 39ed1febc65..65225471d0f 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -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) { diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index f8301943822..5faca56e1d7 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -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" diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 56868be6358..ae1247a7327 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -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; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index e9fabf7aa64..02abfb73b96 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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,18 +1902,17 @@ 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]; float locmat[4][4]; float vec[3]; int ok; - + object_to_mat4(ob, locmat); if(ob->partype & PARSLOW) Mat4CpyMat4(slowmat, obmat); - switch(ob->partype & PARTYPE) { case PAROBJECT: @@ -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); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 783881f25bf..9e8651d9847 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -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 */ } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 8fd12ea50d0..20826b6e268 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -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) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 422218e2957..70a2e9ca3a3 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -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) { diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 99f89d84328..bc4f39d8a23 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -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 diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 09b7f864f3e..33e8c87e6ca 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -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); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index db97665a571..e1b7e283565 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -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 */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 6136a0a99b1..59beb953c8d 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -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 */ diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 111be9c07ae..06812b45f22 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.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); diff --git a/source/blender/editors/object/Makefile b/source/blender/editors/object/Makefile index 9cd95e6c88e..9011f566bc6 100644 --- a/source/blender/editors/object/Makefile +++ b/source/blender/editors/object/Makefile @@ -46,6 +46,7 @@ CPPFLAGS += -I../../blenloader CPPFLAGS += -I../../blenlib CPPFLAGS += -I../../makesdna CPPFLAGS += -I../../makesrna +CPPFLAGS += -I../../python CPPFLAGS += -I../../imbuf # own include diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript index 2f68fcde1e9..7b50c481527 100644 --- a/source/blender/editors/object/SConscript +++ b/source/blender/editors/object/SConscript @@ -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] ) diff --git a/source/blender/editors/object/editconstraint.c b/source/blender/editors/object/editconstraint.c new file mode 100644 index 00000000000..75134a470d7 --- /dev/null +++ b/source/blender/editors/object/editconstraint.c @@ -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); +} diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index c6cbbf90b79..ba1947fa20e 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -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,33 +1465,20 @@ 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]; - - Mat3CpyMat4(mat, ob->parentinv); - VECCOPY(v3, v1); - v3[0]= -v3[0]; - v3[1]= -v3[1]; - v3[2]= -v3[2]; - Mat3MulVecfl(mat, v3); - } + if(ob->parent) { + v1= ob->loc; + v3= ob->parentinv[3]; + + Mat3CpyMat4(mat, ob->parentinv); + VECCOPY(v3, v1); + v3[0]= -v3[0]; + v3[1]= -v3[1]; + v3[2]= -v3[2]; + Mat3MulVecfl(mat, v3); } ob->recalc |= OB_RECALC_OB; } @@ -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); } - - /* 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); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index f9143ce26da..5c916f20e4a 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -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 */ diff --git a/source/blender/python/intern/stubs.c b/source/blender/python/intern/stubs.c index ae069af5d8c..7ee2c69960d 100644 --- a/source/blender/python/intern/stubs.c +++ b/source/blender/python/intern/stubs.c @@ -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() {} |