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:
parent
32d7a06131
commit
7fae6345ab
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user