Fix for bug #17752: the particle modifier convert button didn't

do anything for dupli objects and groups, which could already
be converted with ctrl+shift+A, but convert can do it as well.
This commit is contained in:
Brecht Van Lommel 2008-10-04 19:58:08 +00:00
parent 32d7a06131
commit 7fae6345ab
3 changed files with 125 additions and 93 deletions

@ -76,6 +76,7 @@ void link_to_scene(unsigned short nr);
void make_links_menu(void);
void make_links(short event);
void make_duplilist_real(void);
void make_object_duplilist_real(struct Base *base);
void apply_objects_locrot(void);
void apply_objects_scale(void);
void apply_objects_rot(void);

@ -1248,6 +1248,7 @@ static void modifiers_convertParticles(void *obv, void *mdv)
ModifierData *md = mdv;
ParticleSystem *psys;
ParticleCacheKey *key, **cache;
ParticleSettings *part;
Mesh *me;
MVert *mvert;
MEdge *medge;
@ -1260,78 +1261,90 @@ static void modifiers_convertParticles(void *obv, void *mdv)
if(G.f & G_PARTICLEEDIT) return;
psys=((ParticleSystemModifierData *)md)->psys;
part= psys->part;
if(psys->part->draw_as != PART_DRAW_PATH || psys->pathcache == 0) return;
totpart= psys->totcached;
totchild= psys->totchildcache;
if(totchild && (psys->part->draw&PART_DRAW_PARENT)==0)
totpart= 0;
/* count */
cache= psys->pathcache;
for(a=0; a<totpart; a++) {
key= cache[a];
totvert+= key->steps+1;
totedge+= key->steps;
if(part->draw_as == PART_DRAW_GR || part->draw_as == PART_DRAW_OB) {
make_object_duplilist_real(NULL);
}
else {
if(part->draw_as != PART_DRAW_PATH || psys->pathcache == 0)
return;
cache= psys->childcache;
for(a=0; a<totchild; a++) {
key= cache[a];
totvert+= key->steps+1;
totedge+= key->steps;
}
totpart= psys->totcached;
totchild= psys->totchildcache;
if(totvert==0) return;
if(totchild && (part->draw&PART_DRAW_PARENT)==0)
totpart= 0;
/* add new mesh */
obn= add_object(OB_MESH);
me= obn->data;
me->totvert= totvert;
me->totedge= totedge;
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
mvert= me->mvert;
medge= me->medge;
/* count */
cache= psys->pathcache;
for(a=0; a<totpart; a++) {
key= cache[a];
totvert+= key->steps+1;
totedge+= key->steps;
}
/* copy coordinates */
cache= psys->pathcache;
for(a=0; a<totpart; a++) {
key= cache[a];
kmax= key->steps;
for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
VECCOPY(mvert->co,key->co);
if(k) {
medge->v1= cvert-1;
medge->v2= cvert;
medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
medge++;
cache= psys->childcache;
for(a=0; a<totchild; a++) {
key= cache[a];
totvert+= key->steps+1;
totedge+= key->steps;
}
if(totvert==0) return;
/* add new mesh */
obn= add_object(OB_MESH);
me= obn->data;
me->totvert= totvert;
me->totedge= totedge;
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
mvert= me->mvert;
medge= me->medge;
/* copy coordinates */
cache= psys->pathcache;
for(a=0; a<totpart; a++) {
key= cache[a];
kmax= key->steps;
for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
VECCOPY(mvert->co,key->co);
if(k) {
medge->v1= cvert-1;
medge->v2= cvert;
medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
medge++;
}
}
}
}
cache=psys->childcache;
for(a=0; a<totchild; a++) {
key=cache[a];
kmax=key->steps;
for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
VECCOPY(mvert->co,key->co);
if(k) {
medge->v1=cvert-1;
medge->v2=cvert;
medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
medge++;
cache=psys->childcache;
for(a=0; a<totchild; a++) {
key=cache[a];
kmax=key->steps;
for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
VECCOPY(mvert->co,key->co);
if(k) {
medge->v1=cvert-1;
medge->v2=cvert;
medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
medge++;
}
}
}
}
DAG_scene_sort(G.scene);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWOOPS, 0);
BIF_undo_push("Convert particles to mesh object(s).");
}
static void modifiers_applyModifier(void *obv, void *mdv)
@ -1870,8 +1883,15 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiBlockBeginAlign(block);
if (md->type==eModifierType_ParticleSystem) {
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Convert", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Convert the current particles to a mesh object");
uiButSetFunc(but, modifiers_convertParticles, ob, md);
ParticleSystem *psys;
psys= ((ParticleSystemModifierData *)md)->psys;
if(!(G.f & G_PARTICLEEDIT)) {
if(ELEM3(psys->part->draw_as, PART_DRAW_PATH, PART_DRAW_GR, PART_DRAW_OB) && psys->pathcache) {
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Convert", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Convert the current particles to a mesh object");
uiButSetFunc(but, modifiers_convertParticles, ob, md);
}
}
}
else{
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");

@ -5404,10 +5404,51 @@ void adduplicate(int mode, int dupflag)
}
}
void make_object_duplilist_real(Base *base)
{
Base *basen;
Object *ob;
ListBase *lb;
DupliObject *dob;
if(!base && !(base = BASACT))
return;
if(!(base->object->transflag & OB_DUPLI))
return;
lb= object_duplilist(G.scene, base->object);
for(dob= lb->first; dob; dob= dob->next) {
ob= copy_object(dob->ob);
/* font duplis can have a totcol without material, we get them from parent
* should be implemented better...
*/
if(ob->mat==NULL) ob->totcol= 0;
basen= MEM_dupallocN(base);
basen->flag &= ~OB_FROMDUPLI;
BLI_addhead(&G.scene->base, basen); /* addhead: othwise eternal loop */
basen->object= ob;
ob->ipo= NULL; /* make sure apply works */
ob->parent= ob->track= NULL;
ob->disp.first= ob->disp.last= NULL;
ob->transflag &= ~OB_DUPLI;
Mat4CpyMat4(ob->obmat, dob->mat);
apply_obmat(ob);
}
copy_object_set_idnew(0);
free_object_duplilist(lb);
base->object->transflag &= ~OB_DUPLI;
}
void make_duplilist_real()
{
Base *base, *basen;
Object *ob;
Base *base;
/* extern ListBase duplilist; */
if(okee("Make dupli objects real")==0) return;
@ -5417,37 +5458,7 @@ void make_duplilist_real()
base= FIRSTBASE;
while(base) {
if TESTBASE(base) {
if(base->object->transflag & OB_DUPLI) {
ListBase *lb= object_duplilist(G.scene, base->object);
DupliObject *dob;
for(dob= lb->first; dob; dob= dob->next) {
ob= copy_object(dob->ob);
/* font duplis can have a totcol without material, we get them from parent
* should be implemented better...
*/
if(ob->mat==NULL) ob->totcol= 0;
basen= MEM_dupallocN(base);
basen->flag &= ~OB_FROMDUPLI;
BLI_addhead(&G.scene->base, basen); /* addhead: othwise eternal loop */
basen->object= ob;
ob->ipo= NULL; /* make sure apply works */
ob->parent= ob->track= NULL;
ob->disp.first= ob->disp.last= NULL;
ob->transflag &= ~OB_DUPLI;
Mat4CpyMat4(ob->obmat, dob->mat);
apply_obmat(ob);
}
copy_object_set_idnew(0);
free_object_duplilist(lb);
base->object->transflag &= ~OB_DUPLI;
}
make_object_duplilist_real(base);
}
base= base->next;
}