diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-11-01 03:06:53 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-11-01 03:06:53 +0300 |
commit | 2d0d4e7de4d31bd2f8485a9b7b4311bf8e254c3d (patch) | |
tree | a6f262fc2e8e7762599e12a0c9984fab02ce2bff /source/blender/blenkernel | |
parent | 672c8926d7801fcc4b45e9dff75022e1ff9d240b (diff) |
commit before doing some hefty shapekey change, will break compilation
Diffstat (limited to 'source/blender/blenkernel')
30 files changed, 950 insertions, 520 deletions
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index cc5b4dfdcaf..045095567bc 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -67,6 +67,7 @@ struct KeyingSet *BKE_keyingset_add(struct ListBase *list, const char name[], sh /* Add a destination to a KeyingSet */ void BKE_keyingset_add_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode); +/* Find the destination matching the criteria given */ struct KS_Path *BKE_keyingset_find_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode); /* Copy all KeyingSets in the given list */ @@ -79,6 +80,15 @@ void BKE_keyingset_free(struct KeyingSet *ks); void BKE_keyingsets_free(struct ListBase *list); /* ************************************* */ +/* Path Fixing API */ + +/* Fix all the paths for the given ID+AnimData */ +void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, char *prefix, char *oldName, char *newName); + +/* Fix all the paths for the entire database... */ +void BKE_all_animdata_fix_paths_rename(char *prefix, char *oldName, char *newName); + +/* ************************************* */ // TODO: overrides, remapping, and path-finding api's /* ************************************* */ diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index cbce20a4980..e4a763a25d0 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,7 +43,7 @@ struct bContext; struct ReportList; #define BLENDER_VERSION 250 -#define BLENDER_SUBVERSION 6 +#define BLENDER_SUBVERSION 7 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 78a2f13a7cc..2d1bec09dbf 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -92,6 +92,9 @@ void switchdirectionNurb( struct Nurb *nu); float (*curve_getVertexCos(struct Curve *cu, struct ListBase *lb, int *numVerts_r))[3]; void curve_applyVertexCos(struct Curve *cu, struct ListBase *lb, float (*vertexCos)[3]); +float (*curve_getKeyVertexCos(struct Curve *cu, struct ListBase *lb, float *key))[3]; +void curve_applyKeyVertexTilts(struct Curve *cu, struct ListBase *lb, float *key); + /* nurb checks if they can be drawn, also clamp order func */ int check_valid_nurb_u( struct Nurb *nu); int check_valid_nurb_v( struct Nurb *nu); diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 5d0b89220d5..2e9ac2f65f0 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -110,7 +110,7 @@ typedef struct Global { #define G_BACKBUFSEL (1 << 4) #define G_PICKSEL (1 << 5) -#define G_FACESELECT (1 << 8) +/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_MASK) */ #define G_DEBUG (1 << 12) #define G_DOSCRIPTLINKS (1 << 13) @@ -145,6 +145,7 @@ typedef struct Global { #define G_FILE_GLSL_NO_NODES (1 << 20) /* deprecated */ #define G_FILE_GLSL_NO_EXTRA_TEX (1 << 21) /* deprecated */ #define G_FILE_IGNORE_DEPRECATION_WARNINGS (1 << 22) /* deprecated */ +#define G_FILE_RECOVER (1 << 23) /* G.windowstate */ #define G_WINDOWSTATE_USERDEF 0 diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 4bfa6a41099..b70801a9edd 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -56,17 +56,15 @@ void key_curve_position_weights(float t, float *data, int type); void key_curve_tangent_weights(float t, float *data, int type); void key_curve_normal_weights(float t, float *data, int type); -/* only exported to curve.c! */ -void cp_cu_key(struct Curve *cu, struct KeyBlock *kb, int start, int end); - -int do_ob_key(struct Scene *scene, struct Object *ob); +float *do_ob_key(struct Scene *scene, struct Object *ob); struct Key *ob_get_key(struct Object *ob); struct KeyBlock *ob_get_keyblock(struct Object *ob); struct KeyBlock *key_get_keyblock(struct Key *key, int index); struct KeyBlock *key_get_named_keyblock(struct Key *key, const char name[]); +char *key_get_curValue_rnaPath(struct Key *key, struct KeyBlock *kb); // needed for the GE -void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode); +void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, int mode); #ifdef __cplusplus }; diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 85316dddedf..3ea7cae2c86 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -47,6 +47,7 @@ void test_object_materials(struct ID *id); void init_material(struct Material *ma); struct Material *add_material(char *name); struct Material *copy_material(struct Material *ma); +struct Material *give_node_material(struct Material *ma); /* returns node material or self */ void make_local_material(struct Material *ma); void automatname(struct Material *); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 249da2478b7..5a072da13f5 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -55,7 +55,7 @@ extern "C" { struct EditMesh *BKE_mesh_get_editmesh(struct Mesh *me); void BKE_mesh_end_editmesh(struct Mesh *me, struct EditMesh *em); -struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me); +struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me, struct Object *ob); /* this function recreates a tesselation. @@ -111,7 +111,6 @@ void mesh_calc_normals(struct MVert *mverts, int numVerts, struct MFace *mfaces, /* Return a newly MEM_malloc'd array of all the mesh vertex locations * (_numVerts_r_ may be NULL) */ float (*mesh_getVertexCos(struct Mesh *me, int *numVerts_r))[3]; -float (*mesh_getRefKeyCos(struct Mesh *me, int *numVerts_r))[3]; /* map from uv vertex to face (for select linked, stitch, uv suburf) */ diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 8a3c8c64575..89ac993d71a 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -294,7 +294,7 @@ void modifiers_foreachIDLink(struct Object *ob, struct ModifierData *modifiers_findByType(struct Object *ob, ModifierType type); void modifiers_clearErrors(struct Object *ob); int modifiers_getCageIndex(struct Object *ob, - int *lastPossibleCageIndex_r); + int *lastPossibleCageIndex_r, int virtual_); int modifiers_isSoftbodyEnabled(struct Object *ob); int modifiers_isClothEnabled(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_sequence.h b/source/blender/blenkernel/BKE_sequence.h index f72617c8312..fb3c282b090 100644 --- a/source/blender/blenkernel/BKE_sequence.h +++ b/source/blender/blenkernel/BKE_sequence.h @@ -135,6 +135,7 @@ struct SeqEffectHandle { /* ********************* prototypes *************** */ /* sequence.c */ +void printf_strip(struct Sequence *seq); // extern void seq_free_sequence(struct Scene *scene, struct Sequence *seq); @@ -181,6 +182,7 @@ int check_single_seq(struct Sequence *seq); void fix_single_seq(struct Sequence *seq); int seq_test_overlap(struct ListBase * seqbasep, struct Sequence *test); int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test); +int shuffle_seq_time(ListBase * seqbasep); void free_imbuf_seq(struct ListBase * seqbasep, int check_mem_usage); void seq_update_sound(struct Sequence *seq); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 91279597768..ec927dd30de 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1990,9 +1990,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos *final_r = NULL; if(useDeform) { - if(useDeform > 0 && do_ob_key(scene, ob)) /* shape key makes deform verts */ - deformedVerts = mesh_getVertexCos(me, &numVerts); - else if(inputVertexCos) + if(inputVertexCos) deformedVerts = inputVertexCos; /* Apply all leading deforming modifiers */ @@ -2035,7 +2033,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if(inputVertexCos) deformedVerts = inputVertexCos; else - deformedVerts = mesh_getRefKeyCos(me, &numVerts); + deformedVerts = mesh_getVertexCos(me, &numVerts); } @@ -2248,7 +2246,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D float (*deformedVerts)[3] = NULL; CustomDataMask mask; DerivedMesh *dm, *orcodm = NULL; - int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL); + int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL, 1); LinkNode *datamasks, *curr; int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; @@ -2259,7 +2257,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D } dm = NULL; - md = ob->modifiers.first; + md = modifiers_getVirtualModifierList(ob); /* we always want to keep original indices */ dataMask |= CD_MASK_ORIGINDEX; @@ -2695,13 +2693,13 @@ int editbmesh_get_first_deform_matrices(Object *ob, BMEditMesh *em, float (**def ModifierData *md; DerivedMesh *dm; int i, a, numleft = 0, numVerts = 0; - int cageIndex = modifiers_getCageIndex(ob, NULL); + int cageIndex = modifiers_getCageIndex(ob, NULL, 1); float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL; modifiers_clearErrors(ob); dm = NULL; - md = ob->modifiers.first; + md = modifiers_getVirtualModifierList(ob); /* compute the deformation matrices and coordinates for the first modifiers with on cage editing that are enabled and support computing diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 47f5dd116d7..61e754ffbec 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -238,24 +238,88 @@ void BKE_animdata_make_local(AnimData *adt) /* Path Validation -------------------------------------------- */ -#if 0 -/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate */ -static char *rna_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, char *oldpath) +/* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */ +static short check_rna_path_is_valid (ID *owner_id, char *path) { + PointerRNA id_ptr, ptr; + PropertyRNA *prop=NULL; + /* make initial RNA pointer to start resolving from */ + RNA_id_pointer_create(owner_id, &id_ptr); - return oldpath; // FIXME!!! + /* try to resolve */ + return RNA_path_resolve(&id_ptr, path, &ptr, &prop); +} + +/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate + * NOTE: we assume that oldName and newName have [" "] padding around them + */ +static char *rna_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, char *oldpath) +{ + char *prefixPtr= strstr(oldpath, prefix); + char *oldNamePtr= strstr(oldpath, oldName); + int prefixLen= strlen(prefix); + int oldNameLen= strlen(oldName); + + /* only start fixing the path if the prefix and oldName feature in the path, + * and prefix occurs immediately before oldName + */ + if ( (prefixPtr && oldNamePtr) && (prefixPtr+prefixLen == oldNamePtr) ) { + /* if we haven't aren't able to resolve the path now, try again after fixing it */ + if (check_rna_path_is_valid(owner_id, oldpath) == 0) { + DynStr *ds= BLI_dynstr_new(); + char *postfixPtr= oldNamePtr+oldNameLen; + char *newPath = NULL; + char oldChar; + + /* add the part of the string that goes up to the start of the prefix */ + if (prefixPtr > oldpath) { + oldChar= prefixPtr[0]; + prefixPtr[0]= 0; + BLI_dynstr_append(ds, oldpath); + prefixPtr[0]= oldChar; + } + + /* add the prefix */ + BLI_dynstr_append(ds, prefix); + + /* add the new name (complete with brackets) */ + BLI_dynstr_append(ds, newName); + + /* add the postfix */ + BLI_dynstr_append(ds, postfixPtr); + + /* create new path, and cleanup old data */ + newPath= BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + + /* check if the new path will solve our problems */ + // TODO: will need to check whether this step really helps in practice + if (check_rna_path_is_valid(owner_id, newPath)) { + /* free the old path, and return the new one, since we've solved the issues */ + MEM_freeN(oldpath); + return newPath; + } + else { + /* still couldn't resolve the path... so, might as well just leave it alone */ + MEM_freeN(newPath); + } + } + } + + /* the old path doesn't need to be changed */ + return oldpath; } /* Check RNA-Paths for a list of F-Curves */ -static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *curves) +static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *curves) { FCurve *fcu; /* we need to check every curve... */ for (fcu= curves->first; fcu; fcu= fcu->next) { /* firstly, handle the F-Curve's own path */ - fcu->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, fcu->rna_path); + fcu->rna_path= rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path); /* driver? */ if (fcu->driver) { @@ -264,14 +328,14 @@ static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *new /* driver targets */ for (dtar= driver->targets.first; dtar; dtar=dtar->next) { - dtat->rna_path= rna_path_rename_fix(dtar->id, modPtr, newName, dtar->rna_path); + dtar->rna_path= rna_path_rename_fix(dtar->id, prefix, oldName, newName, dtar->rna_path); } } } } /* Fix all RNA-Paths for Actions linked to NLA Strips */ -static void nlastrips_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *strips) +static void nlastrips_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *strips) { NlaStrip *strip; @@ -279,42 +343,122 @@ static void nlastrips_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *n for (strip= strips->first; strip; strip= strip->next) { /* fix strip's action */ if (strip->act) - fcurves_path_rename_fix(owner_id, modPtr, newName, &strip->act->curves); + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &strip->act->curves); /* ignore own F-Curves, since those are local... */ /* check sub-strips (if metas) */ - nlastrips_path_rename_fix(owner_id, modPtr, newName, &strip->strips); + nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &strip->strips); } } /* Fix all RNA-Paths in the AnimData block used by the given ID block - * - the pointer of interest must not have had its new name assigned already, otherwise - * path matching for this will never work + * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]> + * i.e. pose.pose_channels["Bone"] */ -void BKE_animdata_fix_paths_rename (ID *owner_id, PointerRNA *modPtr, char *newName) +void BKE_animdata_fix_paths_rename (ID *owner_id, AnimData *adt, char *prefix, char *oldName, char *newName) { - AnimData *adt= BKE_animdata_from_id(owner_id); NlaTrack *nlt; + char *oldN, *newN; /* if no AnimData, no need to proceed */ - if (ELEM4(NULL, owner_id, adt, modPtr, newName)) + if (ELEM4(NULL, owner_id, adt, oldName, newName)) return; + /* pad the names with [" "] so that only exact matches are made */ + oldN= BLI_sprintfN("[\"%s\"]", oldName); + newN= BLI_sprintfN("[\"%s\"]", newName); + /* Active action and temp action */ if (adt->action) - fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->action->curves); + fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->action->curves); if (adt->tmpact) - fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->tmpact->curves); + fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->tmpact->curves); /* Drivers - Drivers are really F-Curves */ - fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->drivers); + fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->drivers); /* NLA Data - Animation Data for Strips */ - for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) + nlastrips_path_rename_fix(owner_id, prefix, oldN, newN, &nlt->strips); + + /* free the temp names */ + MEM_freeN(oldN); + MEM_freeN(newN); +} + +/* Fix all RNA-Paths throughout the database (directly access the Global.main version) + * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]> + * i.e. pose.pose_channels["Bone"] + */ +void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newName) +{ + Main *mainptr= G.main; + ID *id; + + /* macro for less typing + * - whether animdata exists is checked for by the main renaming callback, though taking + * this outside of the function may make things slightly faster? + */ +#define RENAMEFIX_ANIM_IDS(first) \ + for (id= first; id; id= id->next) { \ + AnimData *adt= BKE_animdata_from_id(id); \ + BKE_animdata_fix_paths_rename(id, adt, prefix, oldName, newName);\ + } + + /* nodes */ + RENAMEFIX_ANIM_IDS(mainptr->nodetree.first); + + /* textures */ + RENAMEFIX_ANIM_IDS(mainptr->tex.first); + + /* lamps */ + RENAMEFIX_ANIM_IDS(mainptr->lamp.first); + + /* materials */ + RENAMEFIX_ANIM_IDS(mainptr->mat.first); + + /* cameras */ + RENAMEFIX_ANIM_IDS(mainptr->camera.first); + + /* shapekeys */ + RENAMEFIX_ANIM_IDS(mainptr->key.first); + + /* metaballs */ + RENAMEFIX_ANIM_IDS(mainptr->mball.first); + + /* curves */ + RENAMEFIX_ANIM_IDS(mainptr->curve.first); + + /* armatures */ + RENAMEFIX_ANIM_IDS(mainptr->armature.first); + + /* meshes */ + // TODO... + + /* particles */ + RENAMEFIX_ANIM_IDS(mainptr->particle.first); + + /* objects */ + RENAMEFIX_ANIM_IDS(mainptr->object.first); + + /* worlds */ + RENAMEFIX_ANIM_IDS(mainptr->world.first); + + /* scenes */ + for (id= mainptr->scene.first; id; id= id->next) { + AnimData *adt= BKE_animdata_from_id(id); + Scene *scene= (Scene *)id; + + /* do compositing nodes first (since these aren't included in main tree) */ + if (scene->nodetree) { + AnimData *adt2= BKE_animdata_from_id((ID *)scene->nodetree); + BKE_animdata_fix_paths_rename((ID *)scene->nodetree, adt2, prefix, oldName, newName); + } + /* now fix scene animation data as per normal */ + BKE_animdata_fix_paths_rename((ID *)id, adt, prefix, oldName, newName); } } -#endif /* *********************************** */ /* KeyingSet API */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index afc5a972a65..fa0db751c00 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1287,7 +1287,7 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float * - the result should be that the rotations given in the provided pointers have had conversions * applied (as appropriate), such that the rotation of the element hasn't 'visually' changed */ -void BKE_rotMode_change_values (float quat[4], float eul[3], float *axis, float angle[3], short oldMode, short newMode) +void BKE_rotMode_change_values (float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode) { /* check if any change - if so, need to convert data */ if (newMode > 0) { /* to euler */ diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 9c1b93f2bf8..0abe5592da3 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -226,8 +226,6 @@ static void clear_global(void) // free_vertexpaint(); G.main= NULL; - - G.f &= ~(G_FACESELECT); } /* make sure path names are correct for OS */ @@ -281,12 +279,15 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) Object *ob; bScreen *curscreen= NULL; Scene *curscene= NULL; + int recover; char mode; - + /* 'u' = undo save, 'n' = no UI load */ if(bfd->main->screen.first==NULL) mode= 'u'; else if(G.fileflags & G_FILE_NO_UI) mode= 'n'; else mode= 0; + + recover= (G.fileflags & G_FILE_RECOVER); clean_paths(bfd->main); @@ -371,6 +372,16 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) if(G.main->versionfile < 250) do_versions_ipos_to_animato(G.main); // XXX fixme... complicated versionpatching + /* in case of autosave or quit.blend, use original filename instead */ + if(recover && bfd->filename[0]) + filename= bfd->filename; + + /* these are the same at times, should never copy to the same location */ + if(G.sce != filename) + BLI_strncpy(G.sce, filename, FILE_MAX); + + BLI_strncpy(G.main->name, filename, FILE_MAX); /* is guaranteed current file */ + /* baseflags, groups, make depsgraph, etc */ set_scene_bg(CTX_data_scene(C)); @@ -383,11 +394,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) /* now tag update flags, to ensure deformers get calculated on redraw */ DAG_scene_update_flags(CTX_data_scene(C), CTX_data_scene(C)->lay); - if (G.sce != filename) /* these are the same at times, should never copy to the same location */ - strcpy(G.sce, filename); - - BLI_strncpy(G.main->name, filename, FILE_MAX); /* is guaranteed current file */ - MEM_freeN(bfd); } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 2ce877bd847..f31f4cd9753 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1099,8 +1099,7 @@ float *make_orco_curve(Scene *scene, Object *ob) float *fp, *coord_array; int remakeDisp = 0; - if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->refkey) { - cp_cu_key(cu, cu->key->refkey, 0, count_curveverts(&cu->nurb)); + if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->block.first) { makeDispListCurveTypes(scene, ob, 1); remakeDisp = 1; } @@ -1922,7 +1921,7 @@ void makeBevelList(Object *ob) BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0; float min, inp, x1, x2, y1, y2; struct bevelsort *sortdata, *sd, *sd1; - int a, b, nr, poly, resolu, len=0; + int a, b, nr, poly, resolu = 0, len = 0; int do_tilt, do_radius; /* this function needs an object, because of tflag and upflag */ @@ -2905,6 +2904,64 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3]) } } +float (*curve_getKeyVertexCos(Curve *cu, ListBase *lb, float *key))[3] +{ + int i, numVerts; + float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos"); + Nurb *nu; + + co = cos[0]; + for (nu=lb->first; nu; nu=nu->next) { + if (nu->type == CU_BEZIER) { + BezTriple *bezt = nu->bezt; + + for (i=0; i<nu->pntsu; i++,bezt++) { + VECCOPY(co, key); co+=3; key+=3; + VECCOPY(co, key); co+=3; key+=3; + VECCOPY(co, key); co+=3; key+=3; + key++; /* skip tilt */ + } + } + else { + BPoint *bp = nu->bp; + + for(i=0; i<nu->pntsu*nu->pntsv; i++,bp++) { + VECCOPY(co, key); co+=3; key+=3; + key++; /* skip tilt */ + } + } + } + + return cos; +} + +void curve_applyKeyVertexTilts(Curve *cu, ListBase *lb, float *key) +{ + Nurb *nu; + int i; + + for(nu=lb->first; nu; nu=nu->next) { + if(nu->type == CU_BEZIER) { + BezTriple *bezt = nu->bezt; + + for(i=0; i<nu->pntsu; i++,bezt++) { + key+=3*3; + bezt->alfa= *key; + key++; + } + } + else { + BPoint *bp = nu->bp; + + for(i=0; i<nu->pntsu*nu->pntsv; i++,bp++) { + key+=3; + bp->alfa= *key; + key++; + } + } + } +} + int check_valid_nurb_u( struct Nurb *nu ) { if (nu==NULL) return 0; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 2d743a33106..da461f51afb 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -829,7 +829,27 @@ static void layerDefault_mcol(void *data, int count) mcol[i] = default_mcol; } +static void layerInterp_shapekey(void **sources, float *weights, + float *sub_weights, int count, void *dest) +{ + float *co = dest, *src; + float **in = sources; + int i, j, k; + if(count <= 0) return; + + memset(co, 0, sizeof(float)*3); + + sub_weight = sub_weights; + for(i = 0; i < count; ++i) { + float weight = weights ? weights[i] : 1.0f; + + src = in[i]; + co[0] += src[0] * weight; + co[1] += src[1] * weight; + co[2] += src[2] * weight; + } +} const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, @@ -875,13 +895,16 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { layerSwap_mcol, layerDefault_mcol}, {sizeof(MCol)*4, "MCol", 4, "TextureCol", NULL, NULL, layerInterp_mcol, layerSwap_mcol, layerDefault_mcol}, + {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, + {sizeof(float), "", 3, "ShapeKey", layerInterp_shapekey}, }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", - "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol"}; + "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDMPoly", + "CDMLoop", "CDMLoopCol", "CDIDCol", "CDTextureCol", "CDShapeKeyIndex"}; const CustomDataMask CD_MASK_BAREMESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MLOOP | CD_MASK_MPOLY; @@ -893,15 +916,17 @@ const CustomDataMask CD_MASK_MESH = CD_MASK_MTEXPOLY; const CustomDataMask CD_MASK_EDITMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV | - CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | - CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS; + CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX | + CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | + CD_MASK_MDISPS | CD_MASK_SHAPEKEY; const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL; const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | - CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; + CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | + CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX; const CustomDataMask CD_MASK_FACECORNERS = CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 26ea17a296a..d60a26e8feb 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2235,7 +2235,18 @@ void DAG_id_flush_update(ID *id, short flag) } } } - + + /* set flags based on ShapeKey */ + if(idtype == ID_KE) { + for(obt=bmain->object.first; obt; obt= obt->id.next) { + Key *key= ob_get_key(obt); + if(!(ob && obt == ob) && ((ID *)key == id)) { + obt->flag |= (OB_RECALC|OB_RECALC_DATA); + BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); + } + } + } + /* set flags based on particle settings */ if(idtype == ID_PA) { ParticleSystem *psys; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index d8f466835b3..4ef86861685 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1245,6 +1245,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl int editmode = (!forRender && cu->editnurb); float (*originalVerts)[3] = NULL; float (*deformedVerts)[3] = NULL; + float *keyVerts= NULL; int required_mode; if(forRender) required_mode = eModifierMode_Render; @@ -1254,9 +1255,17 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl if(editmode) required_mode |= eModifierMode_Editmode; - if(cu->editnurb==NULL && do_ob_key(scene, ob)) { - deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts); - originalVerts = MEM_dupallocN(deformedVerts); + if(cu->editnurb==NULL) { + keyVerts= do_ob_key(scene, ob); + + if(keyVerts) { + /* split coords from key data, the latter also includes + tilts, which is passed through in the modifier stack. + this is also the reason curves do not use a virtual + shape key modifier yet. */ + deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts); + originalVerts= MEM_dupallocN(deformedVerts); + } } if (preTesselatePoint) { @@ -1270,7 +1279,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl if (mti->type!=eModifierTypeType_OnlyDeform) continue; if (!deformedVerts) { - deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts); + deformedVerts = curve_getVertexCos(cu, nurb, &numVerts); originalVerts = MEM_dupallocN(deformedVerts); } @@ -1281,9 +1290,13 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl } } - if (deformedVerts) { - curve_applyVertexCos(ob->data, nurb, deformedVerts); - } + if (deformedVerts) + curve_applyVertexCos(cu, nurb, deformedVerts); + if (keyVerts) /* these are not passed through modifier stack */ + curve_applyKeyVertexTilts(cu, nurb, keyVerts); + + if(keyVerts) + MEM_freeN(keyVerts); *originalVerts_r = originalVerts; *deformedVerts_r = deformedVerts; diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 2d3b84bbdb3..742214ab28e 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -35,6 +35,9 @@ #include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" +#include "BLI_editVert.h" + #include "DNA_anim_types.h" #include "DNA_curve_types.h" #include "DNA_key_types.h" @@ -53,11 +56,12 @@ #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_mesh.h" +#include "BKE_tessmesh.h" #include "BKE_main.h" #include "BKE_object.h" #include "BKE_utildefines.h" -#include "BLI_blenlib.h" +#include "RNA_access.h" #include "BLI_cellalloc.h" @@ -167,7 +171,7 @@ Key *copy_key(Key *key) while(kbn) { if(kbn->data) kbn->data= MEM_dupallocN(kbn->data); - if( kb==key->refkey ) keyn->refkey= kbn; + if(kb==key->refkey) keyn->refkey= kbn; kbn= kbn->next; kb= kb->next; @@ -496,48 +500,80 @@ static void rel_flerp(int aantal, float *in, float *ref, float *out, float fac) } } -static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *k, float *weights, int mode) +static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **freedata) +{ + if(kb == actkb) { + /* this hack makes it possible to edit shape keys in + edit mode with shape keys blending applied */ + if(GS(key->from->name) == ID_ME) { + Mesh *me; + BMVert *eve; + BMIter iter; + float (*co)[3]; + int a; + + me= (Mesh*)key->from; + + if(me->edit_btmesh && me->edit_btmesh->bm->totvert == kb->totelem) { + a= 0; + co= MEM_callocN(sizeof(float)*3*me->edit_btmesh->bm->totvert, "key_block_get_data"); + + BM_ITER(eve, &iter, me->edit_btmesh->bm, BM_VERTS_OF_MESH, NULL) { + VECCOPY(co[a], eve->co); + a++; + } + + *freedata= (char*)co; + return (char*)co; + } + } + } + + *freedata= NULL; + return kb->data; +} + +static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock *kb, float *weights, int mode) { float ktot = 0.0, kd = 0.0; int elemsize, poinsize = 0, a, *ofsp, ofs[32], flagflo=0; - char *k1, *kref; + char *k1, *kref, *freek1, *freekref; char *cp, elemstr[8]; if(key->from==NULL) return; if( GS(key->from->name)==ID_ME ) { - ofs[0]= sizeof(MVert); + ofs[0]= sizeof(float)*3; ofs[1]= 0; poinsize= ofs[0]; } else if( GS(key->from->name)==ID_LT ) { - ofs[0]= sizeof(BPoint); + ofs[0]= sizeof(float)*3; ofs[1]= 0; poinsize= ofs[0]; } else if( GS(key->from->name)==ID_CU ) { - if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint); - else ofs[0]= sizeof(BezTriple); + if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4; + else ofs[0]= sizeof(float)*10; ofs[1]= 0; poinsize= ofs[0]; } - if(end>tot) end= tot; - k1= k->data; - kref= key->refkey->data; - - if(tot != k->totelem) { + if(tot != kb->totelem) { ktot= 0.0; flagflo= 1; - if(k->totelem) { - kd= k->totelem/(float)tot; + if(kb->totelem) { + kd= kb->totelem/(float)tot; } else return; } + k1= key_block_get_data(key, actkb, kb, &freek1); + kref= key_block_get_data(key, actkb, key->refkey, &freekref); + /* this exception is needed for slurphing */ if(start!=0) { @@ -574,33 +610,24 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * switch(cp[1]) { case IPO_FLOAT: - if(weights) { - memcpy(poin, kref, sizeof(float)*cp[0]); + memcpy(poin, kref, sizeof(float)*3); if(*weights!=0.0f) rel_flerp(cp[0], (float *)poin, (float *)kref, (float *)k1, *weights); weights++; } else - memcpy(poin, k1, sizeof(float)*cp[0]); - - poin+= ofsp[0]; - + memcpy(poin, k1, sizeof(float)*3); break; case IPO_BPOINT: - memcpy(poin, k1, 3*sizeof(float)); - memcpy(poin+4*sizeof(float), k1+3*sizeof(float), sizeof(float)); - - poin+= ofsp[0]; - + memcpy(poin, k1, sizeof(float)*4); break; case IPO_BEZTRIPLE: memcpy(poin, k1, sizeof(float)*10); - poin+= ofsp[0]; - break; } + poin+= ofsp[0]; cp+= 2; ofsp++; } @@ -620,71 +647,63 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * if(mode==KEY_BEZTRIPLE) a+=2; } + + if(freek1) MEM_freeN(freek1); + if(freekref) MEM_freeN(freekref); } -void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end) +static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, int start, int end, char *out, int tot) { Nurb *nu; - int a, step = 0, tot, a1, a2; char *poin; + int a, step, a1, a2; - tot= count_curveverts(&cu->nurb); - nu= cu->nurb.first; - a= 0; - while(nu) { + for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) { if(nu->bp) { - step= nu->pntsu*nu->pntsv; /* exception because keys prefer to work with complete blocks */ - poin= (char *)nu->bp->vec; - poin -= a*sizeof(BPoint); - + poin= out - a*sizeof(float)*4; a1= MAX2(a, start); a2= MIN2(a+step, end); - if(a1<a2) cp_key(a1, a2, tot, poin, cu->key, kb, NULL, KEY_BPOINT); + if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BPOINT); } else if(nu->bezt) { - step= 3*nu->pntsu; - poin= (char *)nu->bezt->vec; - poin -= a*sizeof(BezTriple); - + poin= out - a*sizeof(float)*10; a1= MAX2(a, start); a2= MIN2(a+step, end); - if(a1<a2) cp_key(a1, a2, tot, poin, cu->key, kb, NULL, KEY_BEZTRIPLE); - + if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BEZTRIPLE); } - a+= step; - nu=nu->next; + else + step= 0; } } -void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode) +void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock *actkb, int mode) { KeyBlock *kb; int *ofsp, ofs[3], elemsize, b; char *cp, *poin, *reffrom, *from, elemstr[8]; + char *freefrom, *freereffrom; if(key->from==NULL) return; - if (G.f & G_DEBUG) printf("do_rel_key() \n"); - if( GS(key->from->name)==ID_ME ) { - ofs[0]= sizeof(MVert); + ofs[0]= sizeof(float)*3; ofs[1]= 0; } else if( GS(key->from->name)==ID_LT ) { - ofs[0]= sizeof(BPoint); + ofs[0]= sizeof(float)*3; ofs[1]= 0; } else if( GS(key->from->name)==ID_CU ) { - if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint); - else ofs[0]= sizeof(BezTriple); + if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4; + else ofs[0]= sizeof(float)*10; ofs[1]= 0; } @@ -701,7 +720,7 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode if(mode==KEY_BEZTRIPLE) elemsize*= 3; /* step 1 init */ - cp_key(start, end, tot, basispoin, key, key->refkey, NULL, mode); + cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode); /* step 2: do it */ @@ -709,21 +728,18 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode if(kb!=key->refkey) { float icuval= kb->curval; - if (G.f & G_DEBUG) printf("\tdo rel key %s : %s = %f \n", key->id.name+2, kb->name, icuval); - /* only with value, and no difference allowed */ if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) { KeyBlock *refb; float weight, *weights= kb->weights; - - if (G.f & G_DEBUG) printf("\t\tnot skipped \n"); - - poin= basispoin; - from= kb->data; + /* reference now can be any block */ refb= BLI_findlink(&key->block, kb->relative); if(refb==NULL) continue; - reffrom= refb->data; + + poin= basispoin; + from= key_block_get_data(key, actkb, kb, &freefrom); + reffrom= key_block_get_data(key, actkb, refb, &freereffrom); poin+= start*ofs[0]; reffrom+= key->elemsize*start; // key elemsize yes! @@ -745,17 +761,13 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode switch(cp[1]) { case IPO_FLOAT: - rel_flerp(cp[0], (float *)poin, (float *)reffrom, (float *)from, weight); - + rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, weight); break; case IPO_BPOINT: - rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, icuval); - rel_flerp(1, (float *)(poin+16), (float *)(reffrom+16), (float *)(from+16), icuval); - + rel_flerp(4, (float *)poin, (float *)reffrom, (float *)from, weight); break; case IPO_BEZTRIPLE: - rel_flerp(9, (float *)poin, (float *)reffrom, (float *)from, icuval); - + rel_flerp(10, (float *)poin, (float *)reffrom, (float *)from, weight); break; } @@ -771,38 +783,39 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode if(mode==KEY_BEZTRIPLE) b+= 2; if(weights) weights++; } + + if(freefrom) MEM_freeN(freefrom); + if(freereffrom) MEM_freeN(freereffrom); } } } } -static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock **k, float *t, int mode) +static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, int mode) { float k1tot = 0.0, k2tot = 0.0, k3tot = 0.0, k4tot = 0.0; float k1d = 0.0, k2d = 0.0, k3d = 0.0, k4d = 0.0; int a, ofs[32], *ofsp; int flagdo= 15, flagflo=0, elemsize, poinsize=0; - char *k1, *k2, *k3, *k4; + char *k1, *k2, *k3, *k4, *freek1, *freek2, *freek3, *freek4; char *cp, elemstr[8];; if(key->from==0) return; - if (G.f & G_DEBUG) printf("do_key() \n"); - if( GS(key->from->name)==ID_ME ) { - ofs[0]= sizeof(MVert); + ofs[0]= sizeof(float)*3; ofs[1]= 0; poinsize= ofs[0]; } else if( GS(key->from->name)==ID_LT ) { - ofs[0]= sizeof(BPoint); + ofs[0]= sizeof(float)*3; ofs[1]= 0; poinsize= ofs[0]; } else if( GS(key->from->name)==ID_CU ) { - if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint); - else ofs[0]= sizeof(BezTriple); + if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4; + else ofs[0]= sizeof(float)*10; ofs[1]= 0; poinsize= ofs[0]; @@ -810,10 +823,10 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * if(end>tot) end= tot; - k1= k[0]->data; - k2= k[1]->data; - k3= k[2]->data; - k4= k[3]->data; + k1= key_block_get_data(key, actkb, k[0], &freek1); + k2= key_block_get_data(key, actkb, k[1], &freek2); + k3= key_block_get_data(key, actkb, k[2], &freek3); + k4= key_block_get_data(key, actkb, k[3], &freek4); /* test for more or less points (per key!) */ if(tot != k[0]->totelem) { @@ -921,26 +934,17 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * switch(cp[1]) { case IPO_FLOAT: - flerp(cp[0], (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t); - poin+= ofsp[0]; - + flerp(3, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t); break; case IPO_BPOINT: - flerp(3, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t); - flerp(1, (float *)(poin+16), (float *)(k1+12), (float *)(k2+12), (float *)(k3+12), (float *)(k4+12), t); - - poin+= ofsp[0]; - + flerp(4, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t); break; case IPO_BEZTRIPLE: - flerp(9, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t); - flerp(1, (float *)(poin+36), (float *)(k1+36), (float *)(k2+36), (float *)(k3+36), (float *)(k4+36), t); - poin+= ofsp[0]; - + flerp(10, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t); break; } - + poin+= ofsp[0]; cp+= 2; ofsp++; } @@ -988,6 +992,11 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * if(mode==KEY_BEZTRIPLE) a+= 2; } + + if(freek1) MEM_freeN(freek1); + if(freek2) MEM_freeN(freek2); + if(freek3) MEM_freeN(freek3); + if(freek4) MEM_freeN(freek4); } static float *get_weights_array(Object *ob, char *vgroup) @@ -1037,41 +1046,30 @@ static float *get_weights_array(Object *ob, char *vgroup) return NULL; } -static int do_mesh_key(Scene *scene, Object *ob, Mesh *me) +static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot) { - KeyBlock *k[4]; - float cfra, ctime, t[4], delta, loc[3], size[3]; + KeyBlock *k[4], *actkb= ob_get_keyblock(ob); + float cfra, ctime, t[4], delta; int a, flag = 0, step; - if(me->totvert==0) return 0; - if(me->key==NULL) return 0; - if(me->key->block.first==NULL) return 0; - - /* prevent python from screwing this up? anyhoo, the from pointer could be dropped */ - me->key->from= (ID *)me; - - if (G.f & G_DEBUG) printf("do mesh key ob:%s me:%s ke:%s \n", ob->id.name+2, me->id.name+2, me->key->id.name+2); - - if(me->key->slurph && me->key->type!=KEY_RELATIVE ) { - if (G.f & G_DEBUG) printf("\tslurph key\n"); - - delta= me->key->slurph; - delta/= me->totvert; + if(key->slurph && key->type!=KEY_RELATIVE ) { + delta= key->slurph; + delta/= tot; step= 1; - if(me->totvert>100 && slurph_opt) { - step= me->totvert/50; + if(tot>100 && slurph_opt) { + step= tot/50; delta*= step; /* in do_key and cp_key the case a>tot is handled */ } cfra= (float)scene->r.cfra; - for(a=0; a<me->totvert; a+=step, cfra+= delta) { + for(a=0; a<tot; a+=step, cfra+= delta) { ctime= bsystem_time(scene, 0, cfra, 0.0); // xxx ugly cruft! #if 0 // XXX old animation system - if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) { + if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; CLAMP(ctime, 0.0, 1.0); } @@ -1080,42 +1078,33 @@ static int do_mesh_key(Scene *scene, Object *ob, Mesh *me) ctime /= 100.0f; CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing - flag= setkeys(ctime, &me->key->block, k, t, 0); - if(flag==0) { - - do_key(a, a+step, me->totvert, (char *)me->mvert->co, me->key, k, t, 0); - } - else { - cp_key(a, a+step, me->totvert, (char *)me->mvert->co, me->key, k[2], NULL, 0); - } + flag= setkeys(ctime, &key->block, k, t, 0); + + if(flag==0) + do_key(a, a+step, tot, (char *)out, key, actkb, k, t, 0); + else + cp_key(a, a+step, tot, (char *)out, key, actkb, k[2], NULL, 0); } - - if(flag && k[2]==me->key->refkey) tex_space_mesh(me); - else boundbox_mesh(me, loc, size); } else { - if(me->key->type==KEY_RELATIVE) { + if(key->type==KEY_RELATIVE) { KeyBlock *kb; - if (G.f & G_DEBUG) printf("\tdo relative \n"); - - for(kb= me->key->block.first; kb; kb= kb->next) + for(kb= key->block.first; kb; kb= kb->next) kb->weights= get_weights_array(ob, kb->vgroup); - do_rel_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, 0); + do_rel_key(0, tot, tot, (char *)out, key, actkb, 0); - for(kb= me->key->block.first; kb; kb= kb->next) { + for(kb= key->block.first; kb; kb= kb->next) { if(kb->weights) MEM_freeN(kb->weights); kb->weights= NULL; } } else { - if (G.f & G_DEBUG) printf("\tdo absolute \n"); - ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f); // xxx old cruft #if 0 // XXX old animation system - if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) { + if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; CLAMP(ctime, 0.0, 1.0); } @@ -1124,106 +1113,69 @@ static int do_mesh_key(Scene *scene, Object *ob, Mesh *me) ctime /= 100.0f; CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing - flag= setkeys(ctime, &me->key->block, k, t, 0); - if(flag==0) { - do_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k, t, 0); - } - else { - cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k[2], NULL, 0); - } - - if(flag && k[2]==me->key->refkey) tex_space_mesh(me); - else boundbox_mesh(me, loc, size); + flag= setkeys(ctime, &key->block, k, t, 0); + + if(flag==0) + do_key(0, tot, tot, (char *)out, key, actkb, k, t, 0); + else + cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0); } } - return 1; } -static void do_cu_key(Curve *cu, KeyBlock **k, float *t) +static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, int tot) { Nurb *nu; - int a, step = 0, tot; char *poin; + int a, step; - tot= count_curveverts(&cu->nurb); - nu= cu->nurb.first; - a= 0; - - while(nu) { + for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) { if(nu->bp) { - step= nu->pntsu*nu->pntsv; - - /* exception because keys prefer to work with complete blocks */ - poin= (char *)nu->bp->vec; - poin -= a*sizeof(BPoint); - - do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BPOINT); + poin= out - a*sizeof(float)*4; + do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BPOINT); } else if(nu->bezt) { - step= 3*nu->pntsu; - - poin= (char *)nu->bezt->vec; - poin -= a*sizeof(BezTriple); - - do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BEZTRIPLE); - + poin= out - a*sizeof(float)*10; + do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BEZTRIPLE); } - a+= step; - nu=nu->next; + else + step= 0; } } -static void do_rel_cu_key(Curve *cu, float ctime) +static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, float ctime, char *out, int tot) { Nurb *nu; - int a, step = 0, tot; char *poin; + int a, step; - tot= count_curveverts(&cu->nurb); - nu= cu->nurb.first; - a= 0; - while(nu) { + for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) { if(nu->bp) { - step= nu->pntsu*nu->pntsv; - - /* exception because keys prefer to work with complete blocks */ - poin= (char *)nu->bp->vec; - poin -= a*sizeof(BPoint); - - do_rel_key(a, a+step, tot, poin, cu->key, KEY_BPOINT); + poin= out - a*sizeof(float)*3; + do_rel_key(a, a+step, tot, out, key, actkb, KEY_BPOINT); } else if(nu->bezt) { - step= 3*nu->pntsu; - - poin= (char *)nu->bezt->vec; - poin -= a*sizeof(BezTriple); - - do_rel_key(a, a+step, tot, poin, cu->key, KEY_BEZTRIPLE); + poin= out - a*sizeof(float)*10; + do_rel_key(a, a+step, tot, poin, key, actkb, KEY_BEZTRIPLE); } - a+= step; - - nu=nu->next; + else + step= 0; } } -static int do_curve_key(Scene *scene, Curve *cu) +static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot) { - KeyBlock *k[4]; + Curve *cu= ob->data; + KeyBlock *k[4], *actkb= ob_get_keyblock(ob); float cfra, ctime, t[4], delta; - int a, flag = 0, step = 0, tot; - - tot= count_curveverts(&cu->nurb); + int a, flag = 0, step = 0; - if(tot==0) return 0; - if(cu->key==NULL) return 0; - if(cu->key->block.first==NULL) return 0; - - if(cu->key->slurph) { - delta= cu->key->slurph; + if(key->slurph) { + delta= key->slurph; delta/= tot; step= 1; @@ -1238,66 +1190,52 @@ static int do_curve_key(Scene *scene, Curve *cu) for(a=0; a<tot; a+=step, cfra+= delta) { ctime= bsystem_time(scene, 0, cfra, 0.0f); // XXX old cruft #if 0 // XXX old animation system - if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) { + if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; CLAMP(ctime, 0.0, 1.0); } #endif // XXX old animation system - flag= setkeys(ctime, &cu->key->block, k, t, 0); - if(flag==0) { - - /* do_key(a, a+step, tot, (char *)cu->mvert->co, cu->key, k, t, 0); */ - } - else { - /* cp_key(a, a+step, tot, (char *)cu->mvert->co, cu->key, k[2],0); */ - } - } + flag= setkeys(ctime, &key->block, k, t, 0); - if(flag && k[2]==cu->key->refkey) tex_space_curve(cu); - - + if(flag==0) + ; /* do_key(a, a+step, tot, (char *)out, key, k, t, 0); */ + else + ; /* cp_key(a, a+step, tot, (char *)out, key, k[2],0); */ + } } else { ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0); - if(cu->key->type==KEY_RELATIVE) { - do_rel_cu_key(cu, ctime); + if(key->type==KEY_RELATIVE) { + do_rel_cu_key(cu, cu->key, actkb, ctime, out, tot); } else { #if 0 // XXX old animation system - if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) { + if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; CLAMP(ctime, 0.0, 1.0); } #endif // XXX old animation system - flag= setkeys(ctime, &cu->key->block, k, t, 0); + flag= setkeys(ctime, &key->block, k, t, 0); - if(flag==0) do_cu_key(cu, k, t); - else cp_cu_key(cu, k[2], 0, tot); - - if(flag && k[2]==cu->key->refkey) tex_space_curve(cu); + if(flag==0) do_cu_key(cu, key, actkb, k, t, out, tot); + else cp_cu_key(cu, key, actkb, k[2], 0, tot, out, tot); } } - - return 1; } -static int do_latt_key(Scene *scene, Object *ob, Lattice *lt) +static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot) { - KeyBlock *k[4]; + Lattice *lt= ob->data; + KeyBlock *k[4], *actkb= ob_get_keyblock(ob); float delta, cfra, ctime, t[4]; - int a, tot, flag; + int a, flag; - if(lt->key==NULL) return 0; - if(lt->key->block.first==NULL) return 0; - - tot= lt->pntsu*lt->pntsv*lt->pntsw; - - if(lt->key->slurph) { - delta= lt->key->slurph; + if(key->slurph) { + delta= key->slurph; delta/= (float)tot; cfra= (float)scene->r.cfra; @@ -1306,74 +1244,110 @@ static int do_latt_key(Scene *scene, Object *ob, Lattice *lt) ctime= bsystem_time(scene, 0, cfra, 0.0); // XXX old cruft #if 0 // XXX old animation system - if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) { + if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; CLAMP(ctime, 0.0, 1.0); } #endif // XXX old animation system - flag= setkeys(ctime, <->key->block, k, t, 0); - if(flag==0) { - - do_key(a, a+1, tot, (char *)lt->def->vec, lt->key, k, t, 0); - } - else { - cp_key(a, a+1, tot, (char *)lt->def->vec, lt->key, k[2], NULL, 0); - } + flag= setkeys(ctime, &key->block, k, t, 0); + + if(flag==0) + do_key(a, a+1, tot, (char *)out, key, actkb, k, t, 0); + else + cp_key(a, a+1, tot, (char *)out, key, actkb, k[2], NULL, 0); } } else { - ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0); - - if(lt->key->type==KEY_RELATIVE) { + if(key->type==KEY_RELATIVE) { KeyBlock *kb; - for(kb= lt->key->block.first; kb; kb= kb->next) + for(kb= key->block.first; kb; kb= kb->next) kb->weights= get_weights_array(ob, kb->vgroup); - do_rel_key(0, tot, tot, (char *)lt->def->vec, lt->key, 0); + do_rel_key(0, tot, tot, (char *)out, key, actkb, 0); - for(kb= lt->key->block.first; kb; kb= kb->next) { + for(kb= key->block.first; kb; kb= kb->next) { if(kb->weights) MEM_freeN(kb->weights); kb->weights= NULL; } } else { + ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0); + #if 0 // XXX old animation system - if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) { + if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; CLAMP(ctime, 0.0, 1.0); } #endif // XXX old animation system - flag= setkeys(ctime, <->key->block, k, t, 0); - if(flag==0) { - do_key(0, tot, tot, (char *)lt->def->vec, lt->key, k, t, 0); - } - else { - cp_key(0, tot, tot, (char *)lt->def->vec, lt->key, k[2], NULL, 0); - } + flag= setkeys(ctime, &key->block, k, t, 0); + + if(flag==0) + do_key(0, tot, tot, (char *)out, key, actkb, k, t, 0); + else + cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0); } } if(lt->flag & LT_OUTSIDE) outside_lattice(lt); - - return 1; } -/* returns 1 when key applied */ -int do_ob_key(Scene *scene, Object *ob) +/* returns key coordinates (+ tilt) when key applied, NULL otherwise */ +float *do_ob_key(Scene *scene, Object *ob) { Key *key= ob_get_key(ob); + KeyBlock *actkb= ob_get_keyblock(ob); + char *out; + int tot= 0, size= 0; + + if(key==NULL || key->block.first==NULL) + return NULL; + + /* compute size of output array */ + if(ob->type == OB_MESH) { + Mesh *me= ob->data; + + tot= me->totvert; + size= tot*3*sizeof(float); + } + else if(ob->type == OB_LATTICE) { + Lattice *lt= ob->data; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + size= tot*3*sizeof(float); + } + else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + Curve *cu= ob->data; + Nurb *nu; + + for(nu=cu->nurb.first; nu; nu=nu->next) { + if(nu->bezt) { + tot += 3*nu->pntsu; + size += nu->pntsu*10*sizeof(float); + } + else if(nu->bp) { + tot += nu->pntsu*nu->pntsv; + size += nu->pntsu*nu->pntsv*10*sizeof(float); + } + } + } + + /* if nothing to interpolate, cancel */ + if(tot == 0 || size == 0) + return NULL; - if(key==NULL) - return 0; + /* allocate array */ + out= MEM_callocN(size, "do_ob_key out"); + + /* prevent python from screwing this up? anyhoo, the from pointer could be dropped */ + key->from= (ID *)ob->data; if(ob->shapeflag & OB_SHAPE_LOCK) { + /* shape locked, copy the locked shape instead of blending */ KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1); - if (G.f & G_DEBUG) printf("ob %s, key %s locked \n", ob->id.name+2, key->id.name+2); - if(kb && (kb->flag & KEYBLOCK_MUTE)) kb= key->refkey; @@ -1382,46 +1356,29 @@ int do_ob_key(Scene *scene, Object *ob) ob->shapenr= 1; } - if(ob->type==OB_MESH) { - Mesh *me= ob->data; + if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { float *weights= get_weights_array(ob, kb->vgroup); - cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, key, kb, weights, 0); - - if(weights) MEM_freeN(weights); - } - else if(ob->type==OB_LATTICE) { - Lattice *lt= ob->data; - float *weights= get_weights_array(ob, kb->vgroup); - int tot= lt->pntsu*lt->pntsv*lt->pntsw; - - cp_key(0, tot, tot, (char *)lt->def->vec, key, kb, weights, 0); - + cp_key(0, tot, tot, (char*)out, key, actkb, kb, weights, 0); + if(weights) MEM_freeN(weights); } - else if ELEM(ob->type, OB_CURVE, OB_SURF) { - Curve *cu= ob->data; - int tot= count_curveverts(&cu->nurb); - - cp_cu_key(cu, kb, 0, tot); - } - return 1; + else if(ELEM(ob->type, OB_CURVE, OB_SURF)) + cp_cu_key(ob->data, key, actkb, kb, 0, tot, out, tot); } else { /* do shapekey local drivers */ float ctime= (float)scene->r.cfra; // XXX this needs to be checked - if (G.f & G_DEBUG) - printf("ob %s - do shapekey (%s) drivers \n", ob->id.name+2, key->id.name+2); BKE_animsys_evaluate_animdata(&key->id, key->adt, ctime, ADT_RECALC_DRIVERS); - if(ob->type==OB_MESH) return do_mesh_key(scene, ob, ob->data); - else if(ob->type==OB_CURVE) return do_curve_key(scene, ob->data); - else if(ob->type==OB_SURF) return do_curve_key(scene, ob->data); - else if(ob->type==OB_LATTICE) return do_latt_key(scene, ob, ob->data); + if(ob->type==OB_MESH) do_mesh_key(scene, ob, key, out, tot); + else if(ob->type==OB_LATTICE) do_latt_key(scene, ob, key, out, tot); + else if(ob->type==OB_CURVE) do_curve_key(scene, ob, key, out, tot); + else if(ob->type==OB_SURF) do_curve_key(scene, ob, key, out, tot); } - return 0; + return (float*)out; } Key *ob_get_key(Object *ob) @@ -1490,3 +1447,24 @@ KeyBlock *key_get_named_keyblock(Key *key, const char name[]) return NULL; } + +/* Get RNA-Path for 'value' setting of the given ShapeKey + * NOTE: the user needs to free the returned string once they're finishe with it + */ +char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb) +{ + PointerRNA ptr; + PropertyRNA *prop; + + /* sanity checks */ + if ELEM(NULL, key, kb) + return NULL; + + /* create the RNA pointer */ + RNA_pointer_create(&key->id, &RNA_ShapeKey, kb, &ptr); + /* get pointer to the property too */ + prop= RNA_struct_find_property(&ptr, "value"); + + /* return the path */ + return RNA_path_from_ID_to_property(&ptr, prop); +} diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 0faff6d3354..4ebd36f36c7 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -996,10 +996,6 @@ void lattice_calc_modifiers(Scene *scene, Object *ob) freedisplist(&ob->disp); - if (!editmode) { - do_ob_key(scene, ob); - } - for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index c1093c119dc..c2260e1e761 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -485,6 +485,18 @@ ID *material_from(Object *ob, int act) else return ob->data; } +Material *give_node_material(Material *ma) +{ + if(ma && ma->use_nodes && ma->nodetree) { + bNode *node= nodeGetActiveID(ma->nodetree, ID_MA); + + if(node) + return (Material *)node->id; + } + + return NULL; +} + /* GS reads the memory pointed at in a specific ordering. There are, * however two definitions for it. I have jotted them down here, both, * but I think the first one is actually used. The thing is that @@ -982,7 +994,7 @@ int object_remove_material_slot(Object *ob) /* if g==NULL, it only does r channel */ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) { - float tmp, facm= 1.0-fac; + float tmp, facm= 1.0f-fac; switch (type) { case MA_RAMP_BLEND: @@ -1007,26 +1019,26 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) } break; case MA_RAMP_SCREEN: - *r = 1.0 - (facm + fac*(1.0 - col[0])) * (1.0 - *r); + *r = 1.0f - (facm + fac*(1.0f - col[0])) * (1.0f - *r); if(g) { - *g = 1.0 - (facm + fac*(1.0 - col[1])) * (1.0 - *g); - *b = 1.0 - (facm + fac*(1.0 - col[2])) * (1.0 - *b); + *g = 1.0f - (facm + fac*(1.0f - col[1])) * (1.0f - *g); + *b = 1.0f - (facm + fac*(1.0f - col[2])) * (1.0f - *b); } break; case MA_RAMP_OVERLAY: if(*r < 0.5f) *r *= (facm + 2.0f*fac*col[0]); else - *r = 1.0 - (facm + 2.0f*fac*(1.0 - col[0])) * (1.0 - *r); + *r = 1.0f - (facm + 2.0f*fac*(1.0f - col[0])) * (1.0f - *r); if(g) { if(*g < 0.5f) *g *= (facm + 2.0f*fac*col[1]); else - *g = 1.0 - (facm + 2.0f*fac*(1.0 - col[1])) * (1.0 - *g); + *g = 1.0f - (facm + 2.0f*fac*(1.0f - col[1])) * (1.0f - *g); if(*b < 0.5f) *b *= (facm + 2.0f*fac*col[2]); else - *b = 1.0 - (facm + 2.0f*fac*(1.0 - col[2])) * (1.0 - *b); + *b = 1.0f - (facm + 2.0f*fac*(1.0f - col[2])) * (1.0f - *b); } break; case MA_RAMP_SUB: @@ -1037,12 +1049,12 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) } break; case MA_RAMP_DIV: - if(col[0]!=0.0) + if(col[0]!=0.0f) *r = facm*(*r) + fac*(*r)/col[0]; if(g) { - if(col[1]!=0.0) + if(col[1]!=0.0f) *g = facm*(*g) + fac*(*g)/col[1]; - if(col[2]!=0.0) + if(col[2]!=0.0f) *b = facm*(*b) + fac*(*b)/col[2]; } break; @@ -1076,31 +1088,31 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) case MA_RAMP_DODGE: - if(*r !=0.0){ - tmp = 1.0 - fac*col[0]; - if(tmp <= 0.0) - *r = 1.0; - else if ((tmp = (*r) / tmp)> 1.0) - *r = 1.0; + if(*r !=0.0f){ + tmp = 1.0f - fac*col[0]; + if(tmp <= 0.0f) + *r = 1.0f; + else if ((tmp = (*r) / tmp)> 1.0f) + *r = 1.0f; else *r = tmp; } if(g) { - if(*g !=0.0){ - tmp = 1.0 - fac*col[1]; - if(tmp <= 0.0 ) - *g = 1.0; - else if ((tmp = (*g) / tmp) > 1.0 ) - *g = 1.0; + if(*g !=0.0f){ + tmp = 1.0f - fac*col[1]; + if(tmp <= 0.0f ) + *g = 1.0f; + else if ((tmp = (*g) / tmp) > 1.0f ) + *g = 1.0f; else *g = tmp; } - if(*b !=0.0){ - tmp = 1.0 - fac*col[2]; - if(tmp <= 0.0) - *b = 1.0; - else if ((tmp = (*b) / tmp) > 1.0 ) - *b = 1.0; + if(*b !=0.0f){ + tmp = 1.0f - fac*col[2]; + if(tmp <= 0.0f) + *b = 1.0f; + else if ((tmp = (*b) / tmp) > 1.0f ) + *b = 1.0f; else *b = tmp; } @@ -1111,33 +1123,33 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) tmp = facm + fac*col[0]; - if(tmp <= 0.0) - *r = 0.0; - else if (( tmp = (1.0 - (1.0 - (*r)) / tmp )) < 0.0) - *r = 0.0; - else if (tmp > 1.0) - *r=1.0; + if(tmp <= 0.0f) + *r = 0.0f; + else if (( tmp = (1.0f - (1.0f - (*r)) / tmp )) < 0.0f) + *r = 0.0f; + else if (tmp > 1.0f) + *r=1.0f; else *r = tmp; if(g) { tmp = facm + fac*col[1]; - if(tmp <= 0.0) - *g = 0.0; - else if (( tmp = (1.0 - (1.0 - (*g)) / tmp )) < 0.0 ) - *g = 0.0; - else if(tmp >1.0) - *g=1.0; + if(tmp <= 0.0f) + *g = 0.0f; + else if (( tmp = (1.0f - (1.0f - (*g)) / tmp )) < 0.0f ) + *g = 0.0f; + else if(tmp >1.0f) + *g=1.0f; else *g = tmp; tmp = facm + fac*col[2]; - if(tmp <= 0.0) - *b = 0.0; - else if (( tmp = (1.0 - (1.0 - (*b)) / tmp )) < 0.0 ) - *b = 0.0; - else if(tmp >1.0) - *b= 1.0; + if(tmp <= 0.0f) + *b = 0.0f; + else if (( tmp = (1.0f - (1.0f - (*b)) / tmp )) < 0.0f ) + *b = 0.0f; + else if(tmp >1.0f) + *b= 1.0f; else *b = tmp; } @@ -1197,29 +1209,29 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) float scr, scg, scb; /* first calculate non-fac based Screen mix */ - scr = 1.0 - ((1.0 - col[0])) * (1.0 - *r); - scg = 1.0 - ((1.0 - col[1])) * (1.0 - *g); - scb = 1.0 - ((1.0 - col[2])) * (1.0 - *b); + scr = 1.0f - (1.0f - col[0]) * (1.0f - *r); + scg = 1.0f - (1.0f - col[1]) * (1.0f - *g); + scb = 1.0f - (1.0f - col[2]) * (1.0f - *b); - *r = facm*(*r) + fac*(((1.0 - *r) * col[0] * (*r)) + (*r * scr)); - *g = facm*(*g) + fac*(((1.0 - *g) * col[1] * (*g)) + (*g * scg)); - *b = facm*(*b) + fac*(((1.0 - *b) * col[2] * (*b)) + (*b * scb)); + *r = facm*(*r) + fac*(((1.0f - *r) * col[0] * (*r)) + (*r * scr)); + *g = facm*(*g) + fac*(((1.0f - *g) * col[1] * (*g)) + (*g * scg)); + *b = facm*(*b) + fac*(((1.0f - *b) * col[2] * (*b)) + (*b * scb)); } break; case MA_RAMP_LINEAR: - if (col[0] > 0.5) - *r = *r + fac*(2*(col[0]-0.5)); + if (col[0] > 0.5f) + *r = *r + fac*(2.0f*(col[0]-0.5f)); else - *r = *r + fac*(2*(col[0]) - 1); + *r = *r + fac*(2.0f*(col[0]) - 1.0f); if (g){ - if (col[1] > 0.5) - *g = *g + fac*(2*(col[1]-0.5)); + if (col[1] > 0.5f) + *g = *g + fac*(2.0f*(col[1]-0.5f)); else - *g = *g + fac*(2*(col[1]) -1); - if (col[2] > 0.5) - *b = *b + fac*(2*(col[2]-0.5)); + *g = *g + fac*(2.0f*(col[1]) -1.0f); + if (col[2] > 0.5f) + *b = *b + fac*(2.0f*(col[2]-0.5f)); else - *b = *b + fac*(2*(col[2]) - 1); + *b = *b + fac*(2.0f*(col[2]) - 1.0f); } break; } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 2725d1dc894..f6d1b332e14 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -345,14 +345,14 @@ Mesh *copy_mesh(Mesh *me) return men; } -BMesh *BKE_mesh_to_bmesh(Mesh *me) +BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob) { BMesh *bm; int allocsize[4] = {512,512,2048,512}; bm = BM_Make_Mesh(allocsize); - BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p", me); + BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p object=%p", me, ob); return bm; } @@ -496,35 +496,12 @@ void boundbox_mesh(Mesh *me, float *loc, float *size) void tex_space_mesh(Mesh *me) { - KeyBlock *kb; - float *fp, loc[3], size[3], min[3], max[3]; + float loc[3], size[3]; int a; boundbox_mesh(me, loc, size); if(me->texflag & AUTOSPACE) { - if(me->key) { - kb= me->key->refkey; - if (kb) { - - INIT_MINMAX(min, max); - - fp= kb->data; - for(a=0; a<kb->totelem; a++, fp+=3) { - DO_MINMAX(fp, min, max); - } - if(kb->totelem) { - loc[0]= (min[0]+max[0])/2.0f; loc[1]= (min[1]+max[1])/2.0f; loc[2]= (min[2]+max[2])/2.0f; - size[0]= (max[0]-min[0])/2.0f; size[1]= (max[1]-min[1])/2.0f; size[2]= (max[2]-min[2])/2.0f; - } - else { - loc[0]= loc[1]= loc[2]= 0.0; - size[0]= size[1]= size[2]= 0.0; - } - - } - } - for (a=0; a<3; a++) { if(size[a]==0.0) size[a]= 1.0; else if(size[a]>0.0 && size[a]<0.00001) size[a]= 0.00001; @@ -564,26 +541,20 @@ void mesh_get_texspace(Mesh *me, float *loc_r, float *rot_r, float *size_r) float *get_mesh_orco_verts(Object *ob) { Mesh *me = ob->data; + MVert *mvert = NULL; + Mesh *tme = me->texcomesh?me->texcomesh:me; int a, totvert; float (*vcos)[3] = NULL; /* Get appropriate vertex coordinates */ - if(me->key && me->texcomesh==0 && me->key->refkey) { - vcos= mesh_getRefKeyCos(me, &totvert); - } - else { - MVert *mvert = NULL; - Mesh *tme = me->texcomesh?me->texcomesh:me; + vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh"); + mvert = tme->mvert; + totvert = MIN2(tme->totvert, me->totvert); - vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh"); - mvert = tme->mvert; - totvert = MIN2(tme->totvert, me->totvert); - - for(a=0; a<totvert; a++, mvert++) { - vcos[a][0]= mvert->co[0]; - vcos[a][1]= mvert->co[1]; - vcos[a][2]= mvert->co[2]; - } + for(a=0; a<totvert; a++, mvert++) { + vcos[a][0]= mvert->co[0]; + vcos[a][1]= mvert->co[1]; + vcos[a][2]= mvert->co[2]; } return (float*)vcos; @@ -1354,29 +1325,6 @@ float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3] return cos; } -float (*mesh_getRefKeyCos(Mesh *me, int *numVerts_r))[3] -{ - KeyBlock *kb; - float (*cos)[3] = NULL; - int totvert; - - if(me->key && me->key->refkey) { - if(numVerts_r) *numVerts_r= me->totvert; - - kb= me->key->refkey; - - /* prevent accessing invalid memory */ - if (me->totvert > kb->totelem) cos= MEM_callocN(sizeof(*cos)*me->totvert, "vertexcos1"); - else cos= MEM_mallocN(sizeof(*cos)*me->totvert, "vertexcos1"); - - totvert= MIN2(kb->totelem, me->totvert); - - memcpy(cos, kb->data, sizeof(*cos)*totvert); - } - - return cos; -} - UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit) { UvVertMap *vmap; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index a70d1a02bb4..2ceebd3c0a5 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -64,6 +64,7 @@ #include "DNA_curve_types.h" #include "DNA_effect_types.h" #include "DNA_group_types.h" +#include "DNA_key_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -96,6 +97,7 @@ #include "BKE_fluidsim.h" #include "BKE_global.h" #include "BKE_multires.h" +#include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_material.h" @@ -1196,9 +1198,9 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, /* need to avoid infinite recursion here */ if(amd->start_cap && amd->start_cap != ob) - start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH); + start_cap = amd->start_cap->derivedFinal; if(amd->end_cap && amd->end_cap != ob) - end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH); + end_cap = amd->end_cap->derivedFinal; Mat4One(offset); @@ -5549,7 +5551,7 @@ static DerivedMesh *booleanModifier_applyModifier( { // XXX doesn't handle derived data BooleanModifierData *bmd = (BooleanModifierData*) md; - DerivedMesh *dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_BAREMESH); + DerivedMesh *dm = bmd->object->derivedFinal; /* we do a quick sanity check */ if(dm && (derivedData->getNumTessFaces(derivedData) > 3) @@ -7536,6 +7538,52 @@ static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, BME dm->release(dm); } +/* Shape Key */ + +static void shapekeyModifier_deformVerts( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) +{ + KeyBlock *kb= ob_get_keyblock(ob); + float (*deformedVerts)[3]; + + if(kb && kb->totelem == numVerts) { + deformedVerts= (float(*)[3])do_ob_key(md->scene, ob); + if(deformedVerts) { + memcpy(vertexCos, deformedVerts, sizeof(float)*3*numVerts); + MEM_freeN(deformedVerts); + } + } +} + +static void shapekeyModifier_deformVertsEM( + ModifierData *md, Object *ob, EditMesh *editData, + DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) +{ + Key *key= ob_get_key(ob); + + if(key && key->type == KEY_RELATIVE) + shapekeyModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0); +} + +static void shapekeyModifier_deformMatricesEM( + ModifierData *md, Object *ob, EditMesh *editData, + DerivedMesh *derivedData, float (*vertexCos)[3], + float (*defMats)[3][3], int numVerts) +{ + Key *key= ob_get_key(ob); + KeyBlock *kb= ob_get_keyblock(ob); + float scale[3][3]; + int a; + + if(kb && kb->totelem==numVerts && kb!=key->refkey) { + Mat3Scale(scale, kb->curval); + + for(a=0; a<numVerts; a++) + Mat3CpyMat3(defMats[a], scale); + } +} + /***/ static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES]; @@ -7940,6 +7988,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->copyData = multiresModifier_copyData; mti->applyModifier = multiresModifier_applyModifier; + mti = INIT_TYPE(ShapeKey); + mti->type = eModifierTypeType_OnlyDeform; + mti->flags = eModifierTypeFlag_AcceptsCVs + | eModifierTypeFlag_SupportsEditmode; + mti->deformVerts = shapekeyModifier_deformVerts; + mti->deformVertsEM = shapekeyModifier_deformVertsEM; + mti->deformMatricesEM = shapekeyModifier_deformMatricesEM; + typeArrInit = 0; #undef INIT_TYPE } @@ -8104,9 +8160,9 @@ void modifier_setError(ModifierData *md, char *format, ...) * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg * then is NULL) */ -int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r) +int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r, int virtual_) { - ModifierData *md = ob->modifiers.first; + ModifierData *md = (virtual_)? modifiers_getVirtualModifierList(ob): ob->modifiers.first; int i, cageIndex = -1; /* Find the last modifier acting on the cage. */ @@ -8215,11 +8271,11 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob) static ArmatureModifierData amd; static CurveModifierData cmd; static LatticeModifierData lmd; + static ShapeKeyModifierData smd; static int init = 1; + ModifierData *md; if (init) { - ModifierData *md; - md = modifier_new(eModifierType_Armature); amd = *((ArmatureModifierData*) md); modifier_free(md); @@ -8232,32 +8288,50 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob) lmd = *((LatticeModifierData*) md); modifier_free(md); + md = modifier_new(eModifierType_ShapeKey); + smd = *((ShapeKeyModifierData*) md); + modifier_free(md); + amd.modifier.mode |= eModifierMode_Virtual; cmd.modifier.mode |= eModifierMode_Virtual; lmd.modifier.mode |= eModifierMode_Virtual; + smd.modifier.mode |= eModifierMode_Virtual; init = 0; } - if (ob->parent) { + md = ob->modifiers.first; + + if(ob->parent) { if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) { amd.object = ob->parent; - amd.modifier.next = ob->modifiers.first; + amd.modifier.next = md; amd.deformflag= ((bArmature *)(ob->parent->data))->deformflag; - return &amd.modifier; + md = &amd.modifier; } else if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) { cmd.object = ob->parent; cmd.defaxis = ob->trackflag + 1; - cmd.modifier.next = ob->modifiers.first; - return &cmd.modifier; + cmd.modifier.next = md; + md = &cmd.modifier; } else if(ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) { lmd.object = ob->parent; - lmd.modifier.next = ob->modifiers.first; - return &lmd.modifier; + lmd.modifier.next = md; + md = &lmd.modifier; } } - return ob->modifiers.first; + /* shape key modifier, not yet for curves */ + if(ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) { + if(ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE)) + smd.modifier.mode |= eModifierMode_Editmode|eModifierMode_OnCage; + else + smd.modifier.mode &= ~eModifierMode_Editmode|eModifierMode_OnCage; + + smd.modifier.next = md; + md = &smd.modifier; + } + + return md; } /* Takes an object and returns its first selected armature, else just its * armature @@ -8334,6 +8408,8 @@ int modifier_isDeformer(ModifierData *md) return 1; if (md->type==eModifierType_Lattice) return 1; + if (md->type==eModifierType_ShapeKey) + return 1; return 0; } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 1a89de7e8d6..2776444c8a0 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1198,6 +1198,8 @@ static void node_init_preview(bNode *node, int xsize, int ysize) node->preview->xsize= xsize; node->preview->ysize= ysize; } + else + memset(node->preview->rect, 0, 4*xsize + xsize*ysize*sizeof(float)*4); } void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index cb9748ddb85..964d8d9449f 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1134,6 +1134,8 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) psysn->pathcache= NULL; psysn->childcache= NULL; psysn->edit= NULL; + psysn->frand= NULL; + psysn->pdd= NULL; psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL; psysn->childcachebufs.first = psysn->childcachebufs.last = NULL; diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index f17d2fbdcac..3dfe3966e2f 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -29,6 +29,7 @@ #include "DNA_brush_types.h" #include "DNA_object_types.h" +#include "DNA_mesh_types.h" #include "DNA_scene_types.h" #include "BKE_brush.h" @@ -160,8 +161,7 @@ void paint_brush_slot_remove(Paint *p) int paint_facesel_test(Object *ob) { - return (G.f&G_FACESELECT) && (ob && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))); - + return (ob && ob->data && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))); } void paint_init(Paint *p, const char col[3]) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 555f66c86c8..7e9cf19670e 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2278,15 +2278,20 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c ParticleSettings *part = psys->part; ParticleEditSettings *pset = &scene->toolsettings->particle; int totparent=0, between=0; - int steps = (int)pow(2.0,(double)part->draw_step); + int steps = (int)pow(2.0, (double)part->draw_step); int totchild = psys->totchild; int i, seed, totthread= threads[0].tot; /*---start figuring out what is actually wanted---*/ - if(psys_in_edit_mode(scene, psys)) + if(psys_in_edit_mode(scene, psys)) { + ParticleEditSettings *pset = &scene->toolsettings->particle; + if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0) totchild=0; + steps = (int)pow(2.0, (double)pset->draw_step); + } + if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ totparent=(int)(totchild*part->parents*0.3); @@ -2361,7 +2366,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle ParticleSystem *psys = ctx->sim.psys; ParticleSettings *part = psys->part; ParticleCacheKey **cache= psys->childcache; - ParticleCacheKey **pcache= psys->pathcache; + ParticleCacheKey **pcache= psys_in_edit_mode(ctx->sim.scene, psys) ? psys->edit->pathcache : psys->pathcache; ParticleCacheKey *state, *par = NULL, *key[4]; ParticleData *pa=NULL; ParticleTexture ptex; @@ -2373,6 +2378,9 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle int k, cpa_num; short cpa_from; + if(!pcache) + return; + if(part->flag & PART_BRANCHING) { branch_begin=rng_getFloat(thread->rng_path); branch_end=branch_begin+(1.0f-branch_begin)*rng_getFloat(thread->rng_path); @@ -2955,7 +2963,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf float birthtime = 0.0, dietime = 0.0; float t, time = 0.0, keytime = 0.0, frs_sec; - float hairmat[4][4]; + float hairmat[4][4], rotmat[3][3], prev_tangent[3]; int k,i; int steps = (int)pow(2.0, (double)pset->draw_step); int totpart = edit->totpoint; @@ -2999,8 +3007,12 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf /*--get the first data points--*/ init_particle_interpolation(ob, psys, pa, &pind); - if(psys) + if(psys) { psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + VECCOPY(rotmat[0], hairmat[2]); + VECCOPY(rotmat[1], hairmat[1]); + VECCOPY(rotmat[2], hairmat[0]); + } birthtime = pind.birthtime; dietime = pind.dietime; @@ -3021,9 +3033,55 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); /* non-hair points are allready in global space */ - if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) + if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { Mat4MulVecfl(hairmat, result.co); + /* create rotations for proper creation of children */ + if(k) { + float cosangle, angle, tangent[3], normal[3], q[4]; + + if(k == 1) { + /* calculate initial tangent for incremental rotations */ + VECSUB(tangent, ca->co, (ca - 1)->co); + VECCOPY(prev_tangent, tangent); + Normalize(prev_tangent); + + /* First rotation is based on emitting face orientation. */ + /* This is way better than having flipping rotations resulting */ + /* from using a global axis as a rotation pole (vec_to_quat()). */ + /* It's not an ideal solution though since it disregards the */ + /* initial tangent, but taking that in to account will allow */ + /* the possibility of flipping again. -jahka */ + Mat3ToQuat_is_ok(rotmat, (ca-1)->rot); + } + else { + VECSUB(tangent, ca->co, (ca - 1)->co); + Normalize(tangent); + + cosangle= Inpf(tangent, prev_tangent); + + /* note we do the comparison on cosangle instead of + * angle, since floating point accuracy makes it give + * different results across platforms */ + if(cosangle > 0.999999f) { + QUATCOPY((ca - 1)->rot, (ca - 2)->rot); + } + else { + angle= saacos(cosangle); + Crossf(normal, prev_tangent, tangent); + VecRotToQuat(normal, angle, q); + QuatMul((ca - 1)->rot, q, (ca - 2)->rot); + } + + VECCOPY(prev_tangent, tangent); + } + + if(k == steps) + QUATCOPY(ca->rot, (ca - 1)->rot); + } + + } + VECCOPY(ca->co, result.co); ca->vel[0] = ca->vel[1] = 0.0f; @@ -3054,6 +3112,11 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf } edit->totcached = totpart; + + if(psys && psys->part->type == PART_HAIR) { + ParticleSimulationData sim = {scene, ob, psys, psys_get_modifier(ob, psys), NULL}; + psys_cache_child_paths(&sim, cfra, 1); + } } /************************************************/ /* Particle Key handling */ @@ -3766,6 +3829,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * pind.keyed = keyed; pind.cache = cached ? psys->pointcache : NULL; pind.epoint = NULL; + pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); pind.dm = psys->hair_out_dm; init_particle_interpolation(sim->ob, psys, pa, &pind); do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 00b1672dea6..446bd263f5d 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3504,8 +3504,6 @@ static void psys_changed_physics(ParticleSimulationData *sim) if(part->phystype == PART_PHYS_BOIDS && part->boids == NULL) { BoidState *state; - psys_check_boid_data(sim->psys); - part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings"); boid_default_settings(part->boids); @@ -3518,6 +3516,8 @@ static void psys_changed_physics(ParticleSimulationData *sim) state->flag |= BOIDSTATE_CURRENT; BLI_addtail(&part->boids->states, state); } + + psys_check_boid_data(sim->psys); } static void particles_fluid_step(ParticleSimulationData *sim, int cfra) { diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c index b80df60e726..48eb58687da 100644 --- a/source/blender/blenkernel/intern/sequence.c +++ b/source/blender/blenkernel/intern/sequence.c @@ -69,6 +69,13 @@ static int blender_test_break() {return 0;} /* **** XXX ******** */ +void printf_strip(Sequence *seq) +{ + fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n", + seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp); + fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0)); +} + /* ********************************************************************** alloc / free functions ********************************************************************** */ @@ -3238,7 +3245,7 @@ void seq_tx_set_final_left(Sequence *seq, int val) { if (val < (seq)->start) { seq->startstill = abs(val - (seq)->start); - (seq)->startofs = 0; + seq->startofs = 0; } else { seq->startofs = abs(val - (seq)->start); seq->startstill = 0; @@ -3249,7 +3256,7 @@ void seq_tx_set_final_right(Sequence *seq, int val) { if (val > (seq)->start + (seq)->len) { seq->endstill = abs(val - (seq->start + (seq)->len)); - (seq)->endofs = 0; + seq->endofs = 0; } else { seq->endofs = abs(val - ((seq)->start + (seq)->len)); seq->endstill = 0; @@ -3334,18 +3341,25 @@ int seq_tx_test(Sequence * seq) return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0); } +static int seq_overlap(Sequence *seq1, Sequence *seq2) +{ + if(seq1 != seq2) + if(seq1->machine==seq2->machine) + if(((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp))==0) + return 1; + + return 0; +} + int seq_test_overlap(ListBase * seqbasep, Sequence *test) { Sequence *seq; seq= seqbasep->first; while(seq) { - if(seq!=test) { - if(test->machine==seq->machine) { - if( (test->enddisp <= seq->startdisp) || (test->startdisp >= seq->enddisp) ); - else return 1; - } - } + if(seq_overlap(test, seq)) + return 1; + seq= seq->next; } return 0; @@ -3403,6 +3417,76 @@ int shuffle_seq(ListBase * seqbasep, Sequence *test) } } +static int shuffle_seq_time_offset_test(ListBase * seqbasep, char dir) +{ + int offset= 0; + Sequence *seq, *seq_other; + + for(seq= seqbasep->first; seq; seq= seq->next) { + if(seq->tmp) { + for(seq_other= seqbasep->first; seq_other; seq_other= seq_other->next) { + if(seq_overlap(seq, seq_other)) { + if(dir=='L') { + offset= MIN2(offset, seq_other->startdisp - seq->enddisp); + } + else { + offset= MAX2(offset, seq_other->enddisp - seq->startdisp); + } + } + } + } + } + return offset; +} + +static int shuffle_seq_time_offset(ListBase * seqbasep, char dir) +{ + int ofs= 0; + int tot_ofs= 0; + Sequence *seq; + while( (ofs= shuffle_seq_time_offset_test(seqbasep, dir)) ) { + for(seq= seqbasep->first; seq; seq= seq->next) { + if(seq->tmp) { + /* seq_test_overlap only tests display values */ + seq->startdisp += ofs; + seq->enddisp += ofs; + } + } + + tot_ofs+= ofs; + } + + for(seq= seqbasep->first; seq; seq= seq->next) { + if(seq->tmp) + calc_sequence_disp(seq); /* corrects dummy startdisp/enddisp values */ + } + + return tot_ofs; +} + +int shuffle_seq_time(ListBase * seqbasep) +{ + /* note: seq->tmp is used to tag strips to move */ + + Sequence *seq; + + int offset_l = shuffle_seq_time_offset(seqbasep, 'L'); + int offset_r = shuffle_seq_time_offset(seqbasep, 'R'); + int offset = (-offset_l < offset_r) ? offset_l:offset_r; + + if(offset) { + for(seq= seqbasep->first; seq; seq= seq->next) { + if(seq->tmp) { + seq_translate(seq, offset); + seq->flag &= ~SEQ_OVERLAP; + } + } + } + + return offset? 0:1; +} + + void seq_update_sound(struct Sequence *seq) { if(seq->type == SEQ_SOUND) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index a52a98a1969..194200e0eff 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1027,7 +1027,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd) { SmokeModifierData *smd2 = (SmokeModifierData *)md; - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) + if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points) { // we got nice collision object SmokeCollSettings *scs = smd2->coll; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index dfefc79af9d..be68ebbdaed 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -1706,7 +1706,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], GHash *hash; GHashIterator *ihash; float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3]={0.0,0.0,0.0}, - vv1[3], vv2[3], vv3[3], vv4[3], coledge[3], mindistedge = 1000.0f, + vv1[3], vv2[3], vv3[3], vv4[3], coledge[3]={0.0f, 0.0f, 0.0f}, mindistedge = 1000.0f, outerforceaccu[3],innerforceaccu[3], facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz, innerfacethickness = -0.5f, outerfacethickness = 0.2f, |