diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h index bc95c221b51..11e6478f29a 100644 --- a/source/blender/include/BDR_editobject.h +++ b/source/blender/include/BDR_editobject.h @@ -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); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 007604f77b5..3a819d3d32b 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -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; asteps+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; asteps+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; asteps+1; + totedge+= key->steps; + } - /* copy coordinates */ - cache= psys->pathcache; - for(a=0; asteps; - 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; asteps+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; asteps; + 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; asteps; - 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; asteps; + 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"); diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 250332c4afa..4a70e89dd07 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -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; }