svn merge -r41422:41431 ^/trunk/blender

This commit is contained in:
Campbell Barton 2011-11-01 09:05:38 +00:00
commit 9aa901cccc
28 changed files with 205 additions and 77 deletions

@ -1085,6 +1085,7 @@ class VIEW3D_MT_paint_weight(Menu):
layout.operator("object.vertex_group_normalize_all", text="Normalize All") layout.operator("object.vertex_group_normalize_all", text="Normalize All")
layout.operator("object.vertex_group_normalize", text="Normalize") layout.operator("object.vertex_group_normalize", text="Normalize")
layout.operator("object.vertex_group_mirror", text="Mirror")
layout.operator("object.vertex_group_invert", text="Invert") layout.operator("object.vertex_group_invert", text="Invert")
layout.operator("object.vertex_group_clean", text="Clean") layout.operator("object.vertex_group_clean", text="Clean")
layout.operator("object.vertex_group_levels", text="Levels") layout.operator("object.vertex_group_levels", text="Levels")

@ -1036,6 +1036,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
col.active = ob.vertex_groups.active is not None col.active = ob.vertex_groups.active is not None
col.operator("object.vertex_group_normalize_all", text="Normalize All") col.operator("object.vertex_group_normalize_all", text="Normalize All")
col.operator("object.vertex_group_normalize", text="Normalize") col.operator("object.vertex_group_normalize", text="Normalize")
col.operator("object.vertex_group_mirror", text="Mirror")
col.operator("object.vertex_group_invert", text="Invert") col.operator("object.vertex_group_invert", text="Invert")
col.operator("object.vertex_group_clean", text="Clean") col.operator("object.vertex_group_clean", text="Clean")
col.operator("object.vertex_group_levels", text="Levels") col.operator("object.vertex_group_levels", text="Levels")

@ -45,6 +45,7 @@ struct bDeformGroup *defgroup_duplicate(struct bDeformGroup *ingroup);
struct bDeformGroup *defgroup_find_name(struct Object *ob, const char *name); struct bDeformGroup *defgroup_find_name(struct Object *ob, const char *name);
int defgroup_find_index(struct Object *ob, struct bDeformGroup *dg); int defgroup_find_index(struct Object *ob, struct bDeformGroup *dg);
int *defgroup_flip_map(struct Object *ob, int *flip_map_len, int use_default); int *defgroup_flip_map(struct Object *ob, int *flip_map_len, int use_default);
int *defgroup_flip_map_single(struct Object *ob, int *flip_map_len, int use_default, int defgroup);
int defgroup_flip_index(struct Object *ob, int index, int use_default); int defgroup_flip_index(struct Object *ob, int index, int use_default);
int defgroup_name_index(struct Object *ob, const char *name); int defgroup_name_index(struct Object *ob, const char *name);
void defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob); void defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob);

@ -49,6 +49,7 @@ void *alloc_libblock(struct ListBase *lb, short type, const char *name);
void *copy_libblock(void *rt); void *copy_libblock(void *rt);
void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action); void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action);
void BKE_id_lib_local_paths(struct Main *bmain, struct ID *id);
void id_lib_extern(struct ID *id); void id_lib_extern(struct ID *id);
void BKE_library_filepath_set(struct Library *lib, const char *filepath); void BKE_library_filepath_set(struct Library *lib, const char *filepath);
void id_us_plus(struct ID *id); void id_us_plus(struct ID *id);

@ -146,13 +146,10 @@ void make_local_action(bAction *act)
id_clear_lib_data(bmain, &act->id); id_clear_lib_data(bmain, &act->id);
} }
else if (mlac.is_local && mlac.is_lib) { else if (mlac.is_local && mlac.is_lib) {
char *bpath_user_data[2]= {bmain->name, act->id.lib->filepath};
mlac.actn= copy_action(act); mlac.actn= copy_action(act);
mlac.actn->id.us= 0; mlac.actn->id.us= 0;
/* Remap paths of new ID using old library as base. */ BKE_id_lib_local_paths(bmain, &mlac.actn->id);
bpath_traverse_id(bmain, &mlac.actn->id, bpath_relocate_visitor, 0, bpath_user_data);
BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac); BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac);
} }

@ -157,12 +157,11 @@ void make_local_armature(bArmature *arm)
id_clear_lib_data(bmain, &arm->id); id_clear_lib_data(bmain, &arm->id);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, arm->id.lib->filepath};
bArmature *armn= copy_armature(arm); bArmature *armn= copy_armature(arm);
armn->id.us= 0; armn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &armn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &armn->id);
for(ob= bmain->object.first; ob; ob= ob->id.next) { for(ob= bmain->object.first; ob; ob= ob->id.next) {
if(ob->data == arm) { if(ob->data == arm) {

@ -173,7 +173,7 @@ static void clean_paths(Main *main)
{ {
Scene *scene; Scene *scene;
bpath_traverse_main(main, clean_paths_visit_cb, 0, NULL); bpath_traverse_main(main, clean_paths_visit_cb, BPATH_TRAVERSE_SKIP_MULTIFILE, NULL);
for(scene= main->scene.first; scene; scene= scene->id.next) { for(scene= main->scene.first; scene; scene= scene->id.next) {
BLI_clean(scene->r.pic); BLI_clean(scene->r.pic);

@ -224,13 +224,12 @@ void make_local_brush(Brush *brush)
} }
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, brush->id.lib->filepath};
Brush *brushn= copy_brush(brush); Brush *brushn= copy_brush(brush);
brushn->id.us= 1; /* only keep fake user */ brushn->id.us= 1; /* only keep fake user */
brushn->id.flag |= LIB_FAKEUSER; brushn->id.flag |= LIB_FAKEUSER;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &brushn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &brush->id);
for(scene= bmain->scene.first; scene; scene=scene->id.next) { for(scene= bmain->scene.first; scene; scene=scene->id.next) {
if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {

@ -703,7 +703,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *UNUSED(cob), bC
ct->type = CONSTRAINT_OBTYPE_BONE; \ ct->type = CONSTRAINT_OBTYPE_BONE; \
ct->rotOrder= (pchan) ? (pchan->rotmode) : EULER_ORDER_DEFAULT; \ ct->rotOrder= (pchan) ? (pchan->rotmode) : EULER_ORDER_DEFAULT; \
}\ }\
else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \ else if (OB_TYPE_SUPPORT_VGROUP(ct->tar->type) && (ct->subtarget[0])) { \
ct->type = CONSTRAINT_OBTYPE_VERT; \ ct->type = CONSTRAINT_OBTYPE_VERT; \
ct->rotOrder = EULER_ORDER_DEFAULT; \ ct->rotOrder = EULER_ORDER_DEFAULT; \
} \ } \

@ -274,13 +274,10 @@ void make_local_curve(Curve *cu)
extern_local_curve(cu); extern_local_curve(cu);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, cu->id.lib->filepath};
Curve *cun= copy_curve(cu); Curve *cun= copy_curve(cu);
cun->id.us= 0; cun->id.us= 0;
BKE_id_lib_local_paths(bmain, &cun->id);
/* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &cun->id, bpath_relocate_visitor, 0, bpath_user_data);
for(ob= bmain->object.first; ob; ob= ob->id.next) { for(ob= bmain->object.first; ob; ob= ob->id.next) {
if(ob->data==cu) { if(ob->data==cu) {

@ -260,17 +260,19 @@ int defgroup_find_index (Object *ob, bDeformGroup *dg)
/* note, must be freed */ /* note, must be freed */
int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
{ {
bDeformGroup *dg;
int totdg= *flip_map_len= BLI_countlist(&ob->defbase); int totdg= *flip_map_len= BLI_countlist(&ob->defbase);
if(totdg==0) { if(totdg==0) {
return NULL; return NULL;
} }
else { else {
bDeformGroup *dg;
char name[sizeof(dg->name)]; char name[sizeof(dg->name)];
int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__); int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__);
memset(map, -1, totdg * sizeof(int)); for (i=0; i < totdg; i++) {
map[i]= -1;
}
for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) { for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
if(map[i] == -1) { /* may be calculated previously */ if(map[i] == -1) { /* may be calculated previously */
@ -279,7 +281,7 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
if(use_default) if(use_default)
map[i]= i; map[i]= i;
flip_side_name(name, dg->name, 0); flip_side_name(name, dg->name, FALSE);
if(strcmp(name, dg->name)) { if(strcmp(name, dg->name)) {
flip_num= defgroup_name_index(ob, name); flip_num= defgroup_name_index(ob, name);
if(flip_num >= 0) { if(flip_num >= 0) {
@ -293,6 +295,40 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
} }
} }
/* note, must be freed */
int *defgroup_flip_map_single(Object *ob, int *flip_map_len, int use_default, int defgroup)
{
int totdg= *flip_map_len= BLI_countlist(&ob->defbase);
if(totdg==0) {
return NULL;
}
else {
bDeformGroup *dg;
char name[sizeof(dg->name)];
int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__);
for (i=0; i < totdg; i++) {
if (use_default) map[i]= i;
else map[i]= -1;
}
dg= BLI_findlink(&ob->defbase, defgroup);
flip_side_name(name, dg->name, FALSE);
if(strcmp(name, dg->name)) {
flip_num= defgroup_name_index(ob, name);
if(flip_num >= 0) {
map[defgroup]= flip_num;
map[flip_num]= defgroup;
}
}
return map;
}
}
int defgroup_flip_index(Object *ob, int index, int use_default) int defgroup_flip_index(Object *ob, int index, int use_default)
{ {
bDeformGroup *dg= BLI_findlink(&ob->defbase, index); bDeformGroup *dg= BLI_findlink(&ob->defbase, index);

@ -385,13 +385,12 @@ void make_local_image(struct Image *ima)
extern_local_image(ima); extern_local_image(ima);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, ima->id.lib->filepath};
Image *iman= copy_image(ima); Image *iman= copy_image(ima);
iman->id.us= 0; iman->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &iman->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &iman->id);
tex= bmain->tex.first; tex= bmain->tex.first;
while(tex) { while(tex) {

@ -1429,7 +1429,7 @@ float *do_ob_key(Scene *scene, Object *ob)
ob->shapenr= 1; ob->shapenr= 1;
} }
if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { if (OB_TYPE_SUPPORT_VGROUP(ob->type)) {
float *weights= get_weights_array(ob, kb->vgroup); float *weights= get_weights_array(ob, kb->vgroup);
cp_key(0, tot, tot, out, key, actkb, kb, weights, 0); cp_key(0, tot, tot, out, key, actkb, kb, weights, 0);

@ -271,12 +271,11 @@ void make_local_lattice(Lattice *lt)
id_clear_lib_data(bmain, &lt->id); id_clear_lib_data(bmain, &lt->id);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bath_user_data[2]= {bmain->name, lt->id.lib->filepath};
Lattice *ltn= copy_lattice(lt); Lattice *ltn= copy_lattice(lt);
ltn->id.us= 0; ltn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &ltn->id, bpath_relocate_visitor, 0, bath_user_data); BKE_id_lib_local_paths(bmain, &ltn->id);
for(ob= bmain->object.first; ob; ob= ob->id.next) { for(ob= bmain->object.first; ob; ob= ob->id.next) {
if(ob->data==lt) { if(ob->data==lt) {

@ -127,6 +127,21 @@
/* ************* general ************************ */ /* ************* general ************************ */
/* this has to be called from each make_local_* func, we could call
* from id_make_local() but then the make local functions would not be self
* contained.
* also note that the id _must_ have a library - campbell */
void BKE_id_lib_local_paths(Main *bmain, ID *id)
{
char *bpath_user_data[2]= {bmain->name, (id)->lib->filepath};
bpath_traverse_id(bmain, id,
bpath_relocate_visitor,
BPATH_TRAVERSE_SKIP_MULTIFILE,
bpath_user_data);
}
void id_lib_extern(ID *id) void id_lib_extern(ID *id)
{ {
if(id) { if(id) {
@ -1252,8 +1267,8 @@ int new_id(ListBase *lb, ID *id, const char *tname)
don't have other library users. */ don't have other library users. */
void id_clear_lib_data(Main *bmain, ID *id) void id_clear_lib_data(Main *bmain, ID *id)
{ {
char *bpath_user_data[2]= {bmain->name, id->lib->filepath}; BKE_id_lib_local_paths(bmain, id);
bpath_traverse_id(bmain, id, bpath_relocate_visitor, 0, bpath_user_data);
id->lib= NULL; id->lib= NULL;
id->flag= LIB_LOCAL; id->flag= LIB_LOCAL;
new_id(which_libbase(bmain, GS(id->name)), id, NULL); new_id(which_libbase(bmain, GS(id->name)), id, NULL);

@ -364,13 +364,12 @@ void make_local_material(Material *ma)
} }
/* Both user and local, so copy. */ /* Both user and local, so copy. */
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, ma->id.lib->filepath};
Material *man= copy_material(ma); Material *man= copy_material(ma);
man->id.us= 0; man->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &man->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &man->id);
/* do objects */ /* do objects */
ob= bmain->object.first; ob= bmain->object.first;

@ -174,12 +174,11 @@ void make_local_mball(MetaBall *mb)
extern_local_mball(mb); extern_local_mball(mb);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, mb->id.lib->filepath};
MetaBall *mbn= copy_mball(mb); MetaBall *mbn= copy_mball(mb);
mbn->id.us= 0; mbn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &mbn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &mbn->id);
for(ob= G.main->object.first; ob; ob= ob->id.next) { for(ob= G.main->object.first; ob; ob= ob->id.next) {
if(ob->data == mb) { if(ob->data == mb) {

@ -658,6 +658,8 @@ void make_local_mesh(Mesh *me)
Mesh *men= copy_mesh(me); Mesh *men= copy_mesh(me);
men->id.us= 0; men->id.us= 0;
BKE_id_lib_local_paths(bmain, &men->id);
for(ob= bmain->object.first; ob; ob= ob->id.next) { for(ob= bmain->object.first; ob; ob= ob->id.next) {
if(me == ob->data) { if(me == ob->data) {
if(ob->id.lib==NULL) { if(ob->id.lib==NULL) {

@ -773,13 +773,12 @@ void make_local_camera(Camera *cam)
id_clear_lib_data(bmain, &cam->id); id_clear_lib_data(bmain, &cam->id);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, cam->id.lib->filepath};
Camera *camn= copy_camera(cam); Camera *camn= copy_camera(cam);
camn->id.us= 0; camn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &camn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &camn->id);
for(ob= bmain->object.first; ob; ob= ob->id.next) { for(ob= bmain->object.first; ob; ob= ob->id.next) {
if(ob->data == cam) { if(ob->data == cam) {
@ -940,13 +939,11 @@ void make_local_lamp(Lamp *la)
id_clear_lib_data(bmain, &la->id); id_clear_lib_data(bmain, &la->id);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, la->id.lib->filepath};
Lamp *lan= copy_lamp(la); Lamp *lan= copy_lamp(la);
lan->id.us= 0; lan->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &lan->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &lan->id);
ob= bmain->object.first; ob= bmain->object.first;
while(ob) { while(ob) {
@ -1487,13 +1484,12 @@ void make_local_object(Object *ob)
extern_local_object(ob); extern_local_object(ob);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, ob->id.lib->filepath};
Object *obn= copy_object(ob); Object *obn= copy_object(ob);
obn->id.us= 0; obn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &obn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &obn->id);
sce= bmain->scene.first; sce= bmain->scene.first;
while(sce) { while(sce) {

@ -3634,12 +3634,11 @@ void make_local_particlesettings(ParticleSettings *part)
expand_local_particlesettings(part); expand_local_particlesettings(part);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, part->id.lib->filepath};
ParticleSettings *partn= psys_copy_settings(part); ParticleSettings *partn= psys_copy_settings(part);
partn->id.us= 0; partn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &partn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &partn->id);
/* do objects */ /* do objects */
for(ob= bmain->object.first; ob; ob= ob->id.next) { for(ob= bmain->object.first; ob; ob= ob->id.next) {

@ -106,12 +106,11 @@ void make_local_speaker(Speaker *spk)
id_clear_lib_data(bmain, &spk->id); id_clear_lib_data(bmain, &spk->id);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, spk->id.lib->filepath};
Speaker *spkn= copy_speaker(spk); Speaker *spkn= copy_speaker(spk);
spkn->id.us= 0; spkn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &spkn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &spkn->id);
ob= bmain->object.first; ob= bmain->object.first;
while(ob) { while(ob) {

@ -897,13 +897,12 @@ void make_local_texture(Tex *tex)
extern_local_texture(tex); extern_local_texture(tex);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, tex->id.lib->filepath};
Tex *texn= copy_texture(tex); Tex *texn= copy_texture(tex);
texn->id.us= 0; texn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &texn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &texn->id);
ma= bmain->mat.first; ma= bmain->mat.first;
while(ma) { while(ma) {

@ -176,12 +176,11 @@ void make_local_world(World *wrld)
id_clear_lib_data(bmain, &wrld->id); id_clear_lib_data(bmain, &wrld->id);
} }
else if(is_local && is_lib) { else if(is_local && is_lib) {
char *bpath_user_data[2]= {bmain->name, wrld->id.lib->filepath};
World *wrldn= copy_world(wrld); World *wrldn= copy_world(wrld);
wrldn->id.us= 0; wrldn->id.us= 0;
/* Remap paths of new ID using old library as base. */ /* Remap paths of new ID using old library as base. */
bpath_traverse_id(bmain, &wrldn->id, bpath_relocate_visitor, 0, bpath_user_data); BKE_id_lib_local_paths(bmain, &wrldn->id);
for(sce= bmain->scene.first; sce; sce= sce->id.next) { for(sce= bmain->scene.first; sce; sce= sce->id.next) {
if(sce->world == wrld) { if(sce->world == wrld) {

@ -48,9 +48,13 @@ void bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisito
void bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); void bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata);
int bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); int bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src);
#define BPATH_TRAVERSE_ABS (1<<0) /* convert paths to absolute */ #define BPATH_TRAVERSE_ABS (1<<0) /* convert paths to absolute */
#define BPATH_TRAVERSE_SKIP_LIBRARY (1<<2) /* skip library paths */ #define BPATH_TRAVERSE_SKIP_LIBRARY (1<<2) /* skip library paths */
#define BPATH_TRAVERSE_SKIP_PACKED (1<<3) /* skip packed data */ #define BPATH_TRAVERSE_SKIP_PACKED (1<<3) /* skip packed data */
#define BPATH_TRAVERSE_SKIP_MULTIFILE (1<<4) /* skip paths where a single dir is used with an array of files, eg.
* sequence strip images and pointcache. in this case only use the first
* file, this is needed for directory manipulation functions which might
* otherwise modify the same directory multiple times */
/* high level funcs */ /* high level funcs */

@ -499,6 +499,11 @@ void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int fla
int len= MEM_allocN_len(se) / sizeof(*se); int len= MEM_allocN_len(se) / sizeof(*se);
int i; int i;
if (flag & BPATH_TRAVERSE_SKIP_MULTIFILE) {
/* only operate on one path */
len= MIN2(1, len);
}
for(i= 0; i < len; i++, se++) { for(i= 0; i < len; i++, se++) {
rewrite_path_fixed_dirfile(seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data); rewrite_path_fixed_dirfile(seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data);
} }

@ -255,7 +255,7 @@ void ED_vgroup_select_by_name(struct Object *ob, const char *name);
int ED_vgroup_data_create(struct ID *id); int ED_vgroup_data_create(struct ID *id);
int ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot); int ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
int ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from); int ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from);
void ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups); void ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups, const short all_vgroups);
int ED_vgroup_object_is_edit_mode(struct Object *ob); int ED_vgroup_object_is_edit_mode(struct Object *ob);

@ -102,7 +102,7 @@ bDeformGroup *ED_vgroup_add_name(Object *ob, const char *name)
{ {
bDeformGroup *defgroup; bDeformGroup *defgroup;
if(!ob || !ELEM(ob->type, OB_MESH, OB_LATTICE)) if(!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type))
return NULL; return NULL;
defgroup = MEM_callocN(sizeof(bDeformGroup), "add deformGroup"); defgroup = MEM_callocN(sizeof(bDeformGroup), "add deformGroup");
@ -1531,14 +1531,32 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single)
static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
const char sel, const char sel_mirr, const char sel, const char sel_mirr,
const int *flip_map, const int flip_map_len, const int *flip_map, const int flip_map_len,
const short mirror_weights, const short flip_vgroups) const short mirror_weights, const short flip_vgroups,
const short all_vgroups, const int act_vgroup)
{ {
BLI_assert(sel || sel_mirr); BLI_assert(sel || sel_mirr);
if(sel_mirr && sel) { if(sel_mirr && sel) {
/* swap */ /* swap */
if(mirror_weights) if(mirror_weights) {
SWAP(MDeformVert, *dvert, *dvert_mirr); if (all_vgroups) {
SWAP(MDeformVert, *dvert, *dvert_mirr);
}
else {
MDeformWeight *dw= defvert_find_index(dvert, act_vgroup);
MDeformWeight *dw_mirr= defvert_find_index(dvert_mirr, act_vgroup);
if (dw || dw_mirr) {
if (dw_mirr == NULL)
dw_mirr= defvert_verify_index(dvert_mirr, act_vgroup);
if (dw == NULL)
dw= defvert_verify_index(dvert, act_vgroup);
SWAP(float, dw->weight, dw_mirr->weight);
}
}
}
if(flip_vgroups) { if(flip_vgroups) {
defvert_flip(dvert, flip_map, flip_map_len); defvert_flip(dvert, flip_map, flip_map_len);
defvert_flip(dvert_mirr, flip_map, flip_map_len); defvert_flip(dvert_mirr, flip_map, flip_map_len);
@ -1558,55 +1576,114 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
} }
} }
void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups) /* TODO, vgroup locking */
/* TODO, face masking */
void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups, const short all_vgroups)
{ {
#define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, flip_map_len, mirror_weights, flip_vgroups)
#define VGROUP_MIRR_OP \
dvert_mirror_op(dvert, dvert_mirr, \
sel, sel_mirr, \
flip_map, flip_map_len, \
mirror_weights, flip_vgroups, \
all_vgroups, act_vgroup \
)
BMVert *eve, *eve_mirr; BMVert *eve, *eve_mirr;
MDeformVert *dvert, *dvert_mirr; MDeformVert *dvert, *dvert_mirr;
short sel, sel_mirr; short sel, sel_mirr;
int *flip_map, flip_map_len; int *flip_map, flip_map_len;
const int act_vgroup= ob->actdef > 0 ? ob->actdef-1 : 0;
if(mirror_weights==0 && flip_vgroups==0) if(mirror_weights==0 && flip_vgroups==0)
return; return;
flip_map= defgroup_flip_map(ob, &flip_map_len, FALSE); flip_map= all_vgroups ?
defgroup_flip_map(ob, &flip_map_len, FALSE) :
defgroup_flip_map_single(ob, &flip_map_len, FALSE, act_vgroup);
/* only the active group */ /* only the active group */
if(ob->type == OB_MESH) { if(ob->type == OB_MESH) {
Mesh *me= ob->data; Mesh *me= ob->data;
BMEditMesh *em = me->edit_btmesh; BMEditMesh *em = me->edit_btmesh;
BMIter iter;
if(!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) { if (em) {
MEM_freeN(flip_map); BMIter iter;
return;
if(!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) {
MEM_freeN(flip_map);
return;
}
EDBM_CacheMirrorVerts(em, FALSE);
/* Go through the list of editverts and assign them */
BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
if((eve_mirr= EDBM_GetMirrorVert(em, eve))) {
sel= BM_TestHFlag(eve, BM_SELECT);
sel_mirr= BM_TestHFlag(eve_mirr, BM_SELECT);
if((sel || sel_mirr) && (eve != eve_mirr)) {
dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
dvert_mirr= CustomData_bmesh_get(&em->bm->vdata, eve_mirr->head.data, CD_MDEFORMVERT);
if(dvert && dvert_mirr) {
VGROUP_MIRR_OP;
}
}
/* don't use these again */
EDBM_ClearMirrorVert(em, eve);
EDBM_ClearMirrorVert(em, eve_mirr);
}
}
EDBM_EndMirrorCache(em);
} }
else {
/* object mode / weight paint */
MVert *mv, *mv_mirr;
int vidx, vidx_mirr;
const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
EDBM_CacheMirrorVerts(em, FALSE); if (me->dvert == NULL) {
MEM_freeN(flip_map);
return;
}
/* Go through the list of editverts and assign them */ if (!use_vert_sel) {
BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { sel= sel_mirr= TRUE;
if((eve_mirr= EDBM_GetMirrorVert(em, eve))) { }
sel= BM_TestHFlag(eve, BM_SELECT);
sel_mirr= BM_TestHFlag(eve_mirr, BM_SELECT); /* tag verts we have used */
for(vidx= 0, mv= me->mvert; vidx < me->totvert; vidx++, mv++) {
mv->flag &= ~ME_VERT_TMP_TAG;
}
for(vidx= 0, mv= me->mvert; vidx < me->totvert; vidx++, mv++) {
if ( ((mv->flag & ME_VERT_TMP_TAG) == 0) &&
((vidx_mirr= mesh_get_x_mirror_vert(ob, vidx)) != -1) &&
(vidx != vidx_mirr) &&
((((mv_mirr= me->mvert + vidx_mirr)->flag) & ME_VERT_TMP_TAG) == 0))
{
if (use_vert_sel) {
sel= mv->flag & SELECT;
sel_mirr= mv_mirr->flag & SELECT;
}
if (sel || sel_mirr) {
dvert= &me->dvert[vidx];
dvert_mirr= &me->dvert[vidx_mirr];
if((sel || sel_mirr) && (eve != eve_mirr)) {
dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
dvert_mirr= CustomData_bmesh_get(&em->bm->vdata, eve_mirr->head.data, CD_MDEFORMVERT);
if(dvert && dvert_mirr) {
VGROUP_MIRR_OP; VGROUP_MIRR_OP;
} }
}
/* don't use these again */ mv->flag |= ME_VERT_TMP_TAG;
EDBM_ClearMirrorVert(em, eve); mv_mirr->flag |= ME_VERT_TMP_TAG;
EDBM_ClearMirrorVert(em, eve_mirr); }
} }
} }
EDBM_EndMirrorCache(em);
} }
else if (ob->type == OB_LATTICE) { else if (ob->type == OB_LATTICE) {
Lattice *lt= ob->data; Lattice *lt= ob->data;
@ -2019,7 +2096,7 @@ static int vertex_group_poll(bContext *C)
{ {
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
ID *data= (ob)? ob->data: NULL; ID *data= (ob)? ob->data: NULL;
return (ob && !ob->id.lib && ELEM(ob->type, OB_MESH, OB_LATTICE) && data && !data->lib); return (ob && !ob->id.lib && OB_TYPE_SUPPORT_VGROUP(ob->type) && data && !data->lib);
} }
static int vertex_group_poll_edit(bContext *C) static int vertex_group_poll_edit(bContext *C)
@ -2515,7 +2592,10 @@ static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
{ {
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
ED_vgroup_mirror(ob, RNA_boolean_get(op->ptr,"mirror_weights"), RNA_boolean_get(op->ptr,"flip_group_names")); ED_vgroup_mirror(ob,
RNA_boolean_get(op->ptr,"mirror_weights"),
RNA_boolean_get(op->ptr,"flip_group_names"),
RNA_boolean_get(op->ptr,"all_groups"));
DAG_id_tag_update(&ob->id, OB_RECALC_DATA); DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
@ -2533,7 +2613,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
"flipping when both sides are selected otherwise copy from unselected"; "flipping when both sides are selected otherwise copy from unselected";
/* api callbacks */ /* api callbacks */
ot->poll= vertex_group_poll_edit; ot->poll= vertex_group_poll;
ot->exec= vertex_group_mirror_exec; ot->exec= vertex_group_mirror_exec;
/* flags */ /* flags */
@ -2542,6 +2622,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
/* properties */ /* properties */
RNA_def_boolean(ot->srna, "mirror_weights", TRUE, "Mirror Weights", "Mirror weights"); RNA_def_boolean(ot->srna, "mirror_weights", TRUE, "Mirror Weights", "Mirror weights");
RNA_def_boolean(ot->srna, "flip_group_names", TRUE, "Flip Groups", "Flip vertex group names"); RNA_def_boolean(ot->srna, "flip_group_names", TRUE, "Flip Groups", "Flip vertex group names");
RNA_def_boolean(ot->srna, "all_groups", FALSE, "All Groups", "Mirror all vertex groups weights");
} }

@ -321,6 +321,7 @@ typedef struct DupliObject {
/* check if the object type supports materials */ /* check if the object type supports materials */
#define OB_TYPE_SUPPORT_MATERIAL(_type) ((_type) >= OB_MESH && (_type) <= OB_MBALL) #define OB_TYPE_SUPPORT_MATERIAL(_type) ((_type) >= OB_MESH && (_type) <= OB_MBALL)
#define OB_TYPE_SUPPORT_VGROUP(_type) (ELEM(_type, OB_MESH, OB_LATTICE))
/* partype: first 4 bits: type */ /* partype: first 4 bits: type */
#define PARTYPE 15 #define PARTYPE 15