diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index 757306ed7cb..cae08f8041f 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -47,6 +47,11 @@ typedef struct EditVert unsigned char f, h, f1, hash; int totweight; /* __NLA */ struct MDeformWeight *dw; /* __NLA */ + int keyindex; /* lets hold on to this so that maybe we can have a hope + * of restoring any key information if the number/order + * of verts change. + */ + } EditVert; typedef struct EditEdge diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 6f6bc18ae06..ca757ba5d6e 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -268,6 +268,10 @@ EditVert *addvertlist(float *vec) eve->hash= hashnr++; + /* new verts get keyindex of -1 since they did not + * have a pre-editmode vertex order + */ + eve->keyindex = -1; return eve; } @@ -1013,6 +1017,13 @@ void make_editMesh_real(Mesh *me) eve->no[0]= mvert->no[0]/32767.0; eve->no[1]= mvert->no[1]/32767.0; eve->no[2]= mvert->no[2]/32767.0; + + /* lets overwrite the keyindex of the editvert + * with the order it used to be in before + * editmode + */ + eve->keyindex = a; + #ifdef __NLA /* OLD VERSION */ @@ -1221,13 +1232,13 @@ void load_editMesh() void load_editMesh_real(Mesh *me, int undo) { MFace *mface; - MVert *mvert; + MVert *mvert, *oldverts; MSticky *ms; - KeyBlock *actkey=0; + KeyBlock *actkey=0, *currkey; EditVert *eve; EditVlak *evl; EditEdge *eed; - float *fp, nor[3]; + float *fp, *newkey, *oldkey, nor[3]; int i, a, ototvert; #ifdef __NLA MDeformVert *dvert; @@ -1235,260 +1246,281 @@ void load_editMesh_real(Mesh *me, int undo) #endif ototvert= me->totvert; + + /* lets save the old verts just in case we are actually working on + * a key ... we now do processing of the keys at the end*/ + oldverts = me->mvert; + + /* this one also tests of edges are not in faces: */ + /* eed->f==0: not in face, f==1: draw it */ + /* eed->f1 : flag for dynaface (cylindertest, old engine) */ + /* eve->f1 : flag for dynaface (sphere test, old engine) */ + edge_drawflags(); + /* WATCH IT: in evl->f is punoflag (for vertex normal) */ + vertexnormals( (me->flag & ME_NOPUNOFLIP)==0 ); + + eed= G.eded.first; + while(eed) { + if(eed->f==0) G.totface++; + eed= eed->next; + } + + /* new Face block */ + if(G.totface==0) mface= 0; + else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh1"); + /* nieuw Vertex block */ + if(G.totvert==0) mvert= 0; + else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh2"); + +#ifdef __NLA + if (G.totvert==0) dvert=0; + else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3"); + + if (me->dvert) free_dverts(me->dvert, me->totvert); + me->dvert=dvert; +#endif + + me->mvert= mvert; + + if(me->mface) MEM_freeN(me->mface); + me->mface= mface; + me->totvert= G.totvert; + me->totface= G.totface; + + /* the vertices, abuse ->vn as counter */ + eve= G.edve.first; + a=0; + + while(eve) { + VECCOPY(mvert->co, eve->co); + mvert->mat_nr= 255; /* what was this for, halos? */ + + /* vertex normal */ + VECCOPY(nor, eve->no); + VecMulf(nor, 32767.0); + VECCOPY(mvert->no, nor); +#ifdef __NLA + /* NEW VERSION */ + if (dvert){ + dvert->totweight=eve->totweight; + if (eve->dw){ + dvert->dw = MEM_callocN (sizeof(MDeformWeight)*eve->totweight, + "deformWeight"); + memcpy (dvert->dw, eve->dw, + sizeof(MDeformWeight)*eve->totweight); + usedDvert++; + } + } +#endif + + eve->vn= (EditVert *)(long)(a++); /* counter */ + + mvert->flag= 0; + + mvert->flag= 0; + if(eve->f1==1) mvert->flag |= ME_SPHERETEST; + mvert->flag |= (eve->f & 1); + if (eve->h) mvert->flag |= ME_HIDE; + + eve= eve->next; + mvert++; +#ifdef __NLA + dvert++; +#endif + } + +#ifdef __NLA + /* If we didn't actually need the dverts, get rid of them */ + if (!usedDvert){ + free_dverts(me->dvert, G.totvert); + me->dvert=NULL; + } +#endif + + /* the faces */ + evl= G.edvl.first; + i = 0; + while(evl) { + mface= &((MFace *) me->mface)[i]; + + mface->v1= (unsigned int) evl->v1->vn; + mface->v2= (unsigned int) evl->v2->vn; + mface->v3= (unsigned int) evl->v3->vn; + if(evl->v4) mface->v4= (unsigned int) evl->v4->vn; + + mface->mat_nr= evl->mat_nr; + mface->puno= evl->f; + mface->flag= evl->flag; + + /* mat_nr in vertex */ + if(me->totcol>1) { + mvert= me->mvert+mface->v1; + if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr; + mvert= me->mvert+mface->v2; + if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr; + mvert= me->mvert+mface->v3; + if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr; + if(mface->v4) { + mvert= me->mvert+mface->v4; + if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr; + } + } + + /* watch: evl->e1->f==0 means loose edge */ + + if(evl->e1->f==1) { + mface->edcode |= ME_V1V2; + evl->e1->f= 2; + } + if(evl->e2->f==1) { + mface->edcode |= ME_V2V3; + evl->e2->f= 2; + } + if(evl->e3->f==1) { + if(evl->v4) { + mface->edcode |= ME_V3V4; + } + else { + mface->edcode |= ME_V3V1; + } + evl->e3->f= 2; + } + if(evl->e4 && evl->e4->f==1) { + mface->edcode |= ME_V4V1; + evl->e4->f= 2; + } + + /* no index '0' at location 3 or 4 */ + if(evl->v4) fix_faceindices(mface, evl, 4); + else fix_faceindices(mface, evl, 3); + + i++; + evl= evl->next; + } + + /* add loose edges as a face */ + eed= G.eded.first; + while(eed) { + if( eed->f==0 ) { + mface= &((MFace *) me->mface)[i]; + mface->v1= (unsigned int) eed->v1->vn; + mface->v2= (unsigned int) eed->v2->vn; + test_index_mface(mface, 2); + mface->edcode= ME_V1V2; + i++; + } + eed= eed->next; + } + + tex_space_mesh(me); + + /* tface block, always when undo even when it wasnt used, + this because of empty me pointer */ + if( (me->tface || undo) && me->totface ) { + TFace *tfn, *tf; + + tf=tfn= MEM_callocN(sizeof(TFace)*me->totface, "tface"); + evl= G.edvl.first; + while(evl) { + + *tf= evl->tf; + + if(G.f & G_FACESELECT) { + if( vlakselectedAND(evl, 1) ) tf->flag |= TF_SELECT; + else tf->flag &= ~TF_SELECT; + } + + tf++; + evl= evl->next; + } + /* if undo, me was empty */ + if(me->tface) MEM_freeN(me->tface); + me->tface= tfn; + } + else if(me->tface) { + MEM_freeN(me->tface); + me->tface= NULL; + } + + /* mcol: same as tface... */ + if( (me->mcol || undo) && me->totface) { + unsigned int *mcn, *mc; + + mc=mcn= MEM_mallocN(4*sizeof(int)*me->totface, "mcol"); + evl= G.edvl.first; + while(evl) { + memcpy(mc, evl->tf.col, 4*sizeof(int)); + + mc+=4; + evl= evl->next; + } + if(me->mcol) MEM_freeN(me->mcol); + me->mcol= (MCol *)mcn; + } + else if(me->mcol) { + MEM_freeN(me->mcol); + me->mcol= 0; + } + + /* are there keys? */ if(me->key) { + + /* find the active key */ actkey= me->key->block.first; while(actkey) { if(actkey->flag & SELECT) break; actkey= actkey->next; } + + /* Lets reorder the key data so that things line up roughly + * with the way things were before editmode */ + currkey = me->key->block.first; + while(currkey) { + if(currkey->data) { + fp=newkey= MEM_callocN(me->key->elemsize*G.totvert, + "currkey->data"); + oldkey = currkey->data; + + eve= G.edve.first; + + i = 0; + mvert = me->mvert; + while(eve) { + if (eve->keyindex >= 0) { + if(currkey == actkey) { + if (actkey == me->key->refkey) { + VECCOPY(fp, mvert->co); + } + else { + VECCOPY(fp, mvert->co); + VECCOPY(mvert->co, oldverts[eve->keyindex].co); + } + } + else { + VECCOPY(fp, oldkey + 3 * eve->keyindex); + } + } + else { + VECCOPY(fp, mvert->co); + } + fp+= 3; + ++i; + ++mvert; + eve= eve->next; + } + currkey->totelem= G.totvert; + MEM_freeN(currkey->data); + currkey->data = newkey; + } + currkey= currkey->next; + } + } - - if(actkey && me->key->refkey!=actkey) { - /* active key && not the refkey: only vertices */ - - if(G.totvert) { - if(actkey->data) MEM_freeN(actkey->data); - - fp=actkey->data= MEM_callocN(me->key->elemsize*G.totvert, "actkey->data"); - actkey->totelem= G.totvert; - - eve= G.edve.first; - while(eve) { - VECCOPY(fp, eve->co); - fp+= 3; - eve= eve->next; - } - } - } - else if(me->key && actkey==0) { - /* there are keys, only write changes in mverts */ - /* a bit unpredictable when the amount of vertices differ */ - - eve= G.edve.first; - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - VECCOPY(mvert->co, eve->co); - eve= eve->next; - if(eve==0) break; - } - } - else { - /* when there are keys: the refkey, otherise the mesh */ - - /* this one also tests of edges are not in faces: */ - /* eed->f==0: not in face, f==1: draw it */ - /* eed->f1 : flag for dynaface (cylindertest, old engine) */ - /* eve->f1 : flag for dynaface (sphere test, old engine) */ - edge_drawflags(); - - /* WATCH IT: in evl->f is punoflag (for vertex normal) */ - vertexnormals( (me->flag & ME_NOPUNOFLIP)==0 ); - - eed= G.eded.first; - while(eed) { - if(eed->f==0) G.totface++; - eed= eed->next; - } - - /* new Face block */ - if(G.totface==0) mface= 0; - else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh1"); - /* nieuw Vertex block */ - if(G.totvert==0) mvert= 0; - else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh2"); + if(oldverts) MEM_freeN(oldverts); -#ifdef __NLA - if (G.totvert==0) dvert=0; - else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3"); - - if (me->dvert) free_dverts(me->dvert, me->totvert); - me->dvert=dvert; -#endif - if(me->mvert) MEM_freeN(me->mvert); - me->mvert= mvert; - - if(me->mface) MEM_freeN(me->mface); - me->mface= mface; - me->totvert= G.totvert; - me->totface= G.totface; - - /* the vertices, abuse ->vn as counter */ - eve= G.edve.first; - a=0; - - while(eve) { - VECCOPY(mvert->co, eve->co); - mvert->mat_nr= 255; /* what was this for, halos? */ - - /* vertex normal */ - VECCOPY(nor, eve->no); - VecMulf(nor, 32767.0); - VECCOPY(mvert->no, nor); -#ifdef __NLA - /* NEW VERSION */ - if (dvert){ - dvert->totweight=eve->totweight; - if (eve->dw){ - dvert->dw = MEM_callocN (sizeof(MDeformWeight)*eve->totweight, "deformWeight"); - memcpy (dvert->dw, eve->dw, sizeof(MDeformWeight)*eve->totweight); - usedDvert++; - } - } -#endif - - eve->vn= (EditVert *)(long)(a++); /* counter */ - - mvert->flag= 0; - if(eve->f1==1) mvert->flag |= ME_SPHERETEST; - mvert->flag |= (eve->f & 1); - if (eve->h) mvert->flag |= ME_HIDE; - - eve= eve->next; - mvert++; -#ifdef __NLA - dvert++; -#endif - } - -#ifdef __NLA - /* If we didn't actually need the dverts, get rid of them */ - if (!usedDvert){ - free_dverts(me->dvert, G.totvert); - me->dvert=NULL; - } -#endif - - /* the faces */ - evl= G.edvl.first; - i = 0; - while(evl) { - mface= &((MFace *) me->mface)[i]; - - mface->v1= (unsigned int) evl->v1->vn; - mface->v2= (unsigned int) evl->v2->vn; - mface->v3= (unsigned int) evl->v3->vn; - if(evl->v4) mface->v4= (unsigned int) evl->v4->vn; - - mface->mat_nr= evl->mat_nr; - mface->puno= evl->f; - mface->flag= evl->flag; - - /* mat_nr in vertex */ - if(me->totcol>1) { - mvert= me->mvert+mface->v1; - if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr; - mvert= me->mvert+mface->v2; - if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr; - mvert= me->mvert+mface->v3; - if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr; - if(mface->v4) { - mvert= me->mvert+mface->v4; - if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr; - } - } - - /* watch: evl->e1->f==0 means loose edge */ - - if(evl->e1->f==1) { - mface->edcode |= ME_V1V2; - evl->e1->f= 2; - } - if(evl->e2->f==1) { - mface->edcode |= ME_V2V3; - evl->e2->f= 2; - } - if(evl->e3->f==1) { - if(evl->v4) { - mface->edcode |= ME_V3V4; - } - else { - mface->edcode |= ME_V3V1; - } - evl->e3->f= 2; - } - if(evl->e4 && evl->e4->f==1) { - mface->edcode |= ME_V4V1; - evl->e4->f= 2; - } - - /* no index '0' at location 3 or 4 */ - if(evl->v4) fix_faceindices(mface, evl, 4); - else fix_faceindices(mface, evl, 3); - - i++; - evl= evl->next; - } - - /* add loose edges as a face */ - eed= G.eded.first; - while(eed) { - if( eed->f==0 ) { - mface= &((MFace *) me->mface)[i]; - mface->v1= (unsigned int) eed->v1->vn; - mface->v2= (unsigned int) eed->v2->vn; - test_index_mface(mface, 2); - mface->edcode= ME_V1V2; - i++; - } - eed= eed->next; - } - - tex_space_mesh(me); - if(actkey) mesh_to_key(me, actkey); - - /* tface block, always when undo even when it wasnt used, this because of empty me pointer */ - if( (me->tface || undo) && me->totface ) { - TFace *tfn, *tf; - - tf=tfn= MEM_callocN(sizeof(TFace)*me->totface, "tface"); - evl= G.edvl.first; - while(evl) { - - *tf= evl->tf; - - if(G.f & G_FACESELECT) { - if( vlakselectedAND(evl, 1) ) tf->flag |= TF_SELECT; - else tf->flag &= ~TF_SELECT; - } - - tf++; - evl= evl->next; - } - /* if undo, me was empty */ - if(me->tface) MEM_freeN(me->tface); - me->tface= tfn; - } - else if(me->tface) { - MEM_freeN(me->tface); - me->tface= NULL; - } - - /* mcol: same as tface... */ - if( (me->mcol || undo) && me->totface) { - unsigned int *mcn, *mc; - - mc=mcn= MEM_mallocN(4*sizeof(int)*me->totface, "mcol"); - evl= G.edvl.first; - while(evl) { - - memcpy(mc, evl->tf.col, 4*sizeof(int)); - - mc+=4; - evl= evl->next; - } - - if(me->mcol) MEM_freeN(me->mcol); - me->mcol= (MCol *)mcn; - } - else if(me->mcol) { - MEM_freeN(me->mcol); - me->mcol= NULL; - } - } - if(actkey) do_spec_key(me->key); /* te be sure: clear ->vn pointers */ @@ -1515,7 +1547,6 @@ void load_editMesh_real(Mesh *me, int undo) waitcursor(0); } - void remake_editMesh(void) { undo_push_mesh("Undo all changes");