diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2006-11-12 02:23:15 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2006-11-12 02:23:15 +0300 |
commit | e4a1eb4e09384aee760d45db1841666c92972743 (patch) | |
tree | b83af584c08afa2e08c21da528d4defde8813bf9 /source | |
parent | 8857f4ce86cd277d45e513ef1025cd91c4c74753 (diff) |
Added custom vertex data support to editmode. Only used for vertex groups
now, others can be added later (sticky, shape keys). Beside one small fix
for knife exact vertex group interpolation, is intended to work the same
as before.
Also fixes bug #5200, related to editmode undo and vertex groups. And
corrects the editmode to faceselect mode selection conversion, that was
broken in a previous commit.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 36 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 93 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_editVert.h | 6 | ||||
-rw-r--r-- | source/blender/include/BIF_editmesh.h | 10 | ||||
-rw-r--r-- | source/blender/include/editmesh.h | 2 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 14 | ||||
-rw-r--r-- | source/blender/src/drawview.c | 20 | ||||
-rw-r--r-- | source/blender/src/editdeform.c | 83 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 121 | ||||
-rw-r--r-- | source/blender/src/editmesh_add.c | 18 | ||||
-rw-r--r-- | source/blender/src/editmesh_lib.c | 224 | ||||
-rw-r--r-- | source/blender/src/editmesh_mods.c | 26 | ||||
-rw-r--r-- | source/blender/src/editmesh_tools.c | 180 | ||||
-rw-r--r-- | source/blender/src/editobject.c | 16 | ||||
-rw-r--r-- | source/blender/src/retopo.c | 2 | ||||
-rw-r--r-- | source/blender/src/verse_mesh.c | 6 |
18 files changed, 424 insertions, 452 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 9733c26ade2..b36ab67f5e1 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -72,12 +72,16 @@ void CustomData_free(struct CustomData *data); * (flag & LAYERFLAG_NOFREE) is true * grows the number of layers in data if data->maxLayers has been reached * returns 1 on success, 0 on failure + * + * in editmode, use EM_add_data_layer instead of this function */ int CustomData_add_layer(struct CustomData *data, int type, int flag, void *layer); /* frees the first data layer with the give type. * returns 1 on succes, 0 if no layer with the given type is found + * + * in editmode, use EM_free_data_layer instead of this function */ int CustomData_free_layer(struct CustomData *data, int type); @@ -98,7 +102,8 @@ int CustomData_has_layer(const struct CustomData *data, int type); int CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count); -int CustomData_em_copy_data(struct CustomData *data, void *src_block, +int CustomData_em_copy_data(const struct CustomData *source, + struct CustomData *dest, void *src_block, void **dest_block); /* frees data in a CustomData object diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 04cb371226b..f1285032802 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1459,7 +1459,6 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob, float (*vertexCos)[3]) { EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm"); - Mesh *me = ob->data; DM_init(&emdm->dm, BLI_countlist(&em->verts), BLI_countlist(&em->edges), BLI_countlist(&em->faces)); @@ -1492,16 +1491,15 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob, emdm->em = em; emdm->vertexCos = vertexCos; - if(me->dvert) { + if(CustomData_has_layer(&em->vdata, LAYERTYPE_MDEFORMVERT)) { EditVert *eve; int i; + DM_add_vert_layer(&emdm->dm, LAYERTYPE_MDEFORMVERT, 0, NULL); - for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i) { - if(eve->keyindex != -1) - DM_set_vert_data(&emdm->dm, i, LAYERTYPE_MDEFORMVERT, - &me->dvert[eve->keyindex]); - } + for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i) + DM_set_vert_data(&emdm->dm, i, LAYERTYPE_MDEFORMVERT, + CustomData_em_get(&em->vdata, eve->data, LAYERTYPE_MDEFORMVERT)); } if(vertexCos) { diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 21ad73aa240..9dc89760195 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -747,24 +747,25 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me) EditVert *eve; EditEdge *eed; EditFace *efa; - int i; MVert *mvert = CDDM_get_verts(dm); MEdge *medge = CDDM_get_edges(dm); MFace *mface = CDDM_get_faces(dm); + int i, hassticky = 0, hasdvert = 0, hastface = 0, hasmcol = 0; int *index; - TFace *tf; /* set eve->hash to vert index */ for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i) eve->hash = i; - if(me->msticky) - CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL); - if(me->dvert) - CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL); - - if(me->tface) - CustomData_add_layer(&dm->faceData, LAYERTYPE_TFACE, 0, NULL); + /* check for availability of layers */ + if(CustomData_has_layer(&em->vdata, LAYERTYPE_MSTICKY)) + hassticky= CustomData_add_layer(&dm->vertData, LAYERTYPE_MSTICKY, 0, NULL); + if(CustomData_has_layer(&em->vdata, LAYERTYPE_MDEFORMVERT)) + hasdvert= CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL); + if(CustomData_has_layer(&em->vdata, LAYERTYPE_TFACE)) + hastface= CustomData_add_layer(&dm->vertData, LAYERTYPE_TFACE, 0, NULL); + if(CustomData_has_layer(&em->vdata, LAYERTYPE_MCOL)) + hasmcol= CustomData_add_layer(&dm->vertData, LAYERTYPE_MCOL, 0, NULL); /* Need to be able to mark loose edges */ for(eed = em->edges.first; eed; eed = eed->next) { @@ -793,12 +794,12 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me) *index = i; - if(me->msticky && eve->keyindex != -1) + if(hassticky) DM_set_vert_data(dm, i, LAYERTYPE_MSTICKY, - &me->msticky[eve->keyindex]); - if(me->dvert && eve->keyindex != -1) + CustomData_em_get(&em->vdata, eve->data, LAYERTYPE_MSTICKY)); + if(hasdvert) DM_set_vert_data(dm, i, LAYERTYPE_MDEFORMVERT, - &me->dvert[eve->keyindex]); + CustomData_em_get(&em->vdata, eve->data, LAYERTYPE_MDEFORMVERT)); } index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX); @@ -833,9 +834,12 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me) *index = i; - tf = CustomData_em_get(&em->fdata, efa->data, LAYERTYPE_TFACE); - if(tf) - DM_set_face_data(dm, i, LAYERTYPE_TFACE, tf); + if(hastface) + DM_set_face_data(dm, i, LAYERTYPE_TFACE, + CustomData_em_get(&em->fdata, efa->data, LAYERTYPE_TFACE)); + if(hasmcol) + DM_set_face_data(dm, i, LAYERTYPE_MCOL, + CustomData_em_get(&em->fdata, efa->data, LAYERTYPE_MCOL)); } return dm; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 9173a9e0758..c626c79bdcc 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -161,12 +161,17 @@ static void layerInterp_mdeformvert(void **sources, float *weights, /* now we know how many unique deform weights there are, so realloc */ if(dvert->dw) MEM_freeN(dvert->dw); - dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight, - "layerInterp_mdeformvert dvert->dw"); - dvert->totweight = totweight; - for(i = 0, node = dest_dw; node; node = node->next, ++i) - dvert->dw[i] = *((MDeformWeight *)node->link); + if(totweight) { + dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight, + "layerInterp_mdeformvert dvert->dw"); + dvert->totweight = totweight; + + for(i = 0, node = dest_dw; node; node = node->next, ++i) + dvert->dw[i] = *((MDeformWeight *)node->link); + } + else + memset(dvert, 0, sizeof(*dvert)); BLI_linklist_free(dest_dw, linklist_free_simple); } @@ -694,12 +699,34 @@ void CustomData_set_num_elems(CustomData *data, int numElems) /* EditMesh functions */ +void CustomData_em_free_block(CustomData *data, void **block) +{ + const LayerTypeInfo *typeInfo; + int i; + + if(!*block) return; + + for(i = 0; i < data->numLayers; ++i) { + if(!(data->layers[i].flag & LAYERFLAG_NOFREE)) { + typeInfo = layerType_getInfo(data->layers[i].type); + + if(typeInfo->free) { + int offset = data->layers[i].offset; + typeInfo->free((char*)*block + offset, 1, typeInfo->size); + } + } + } + + MEM_freeN(*block); + *block = NULL; +} + static void CustomData_em_alloc_block(CustomData *data, void **block) { /* TODO: optimize free/alloc */ if (*block) - MEM_freeN(*block); + CustomData_em_free_block(data, block); if (data->totSize > 0) *block = MEM_callocN(data->totSize, "CustomData EM block"); @@ -707,34 +734,48 @@ static void CustomData_em_alloc_block(CustomData *data, void **block) *block = NULL; } -void CustomData_em_free_block(CustomData *data, void **block) -{ - if (*block) { - MEM_freeN(*block); - *block = NULL; - } -} - -int CustomData_em_copy_data(CustomData *data, void *src_block, void **dest_block) +int CustomData_em_copy_data(const CustomData *source, CustomData *dest, + void *src_block, void **dest_block) { const LayerTypeInfo *type_info; - int i; + int dest_i, src_i; if (!*dest_block) - CustomData_em_alloc_block(data, dest_block); + CustomData_em_alloc_block(dest, dest_block); /* copies a layer at a time */ - for(i = 0; i < data->numLayers; ++i) { - int offset = data->layers[i].offset; - char *src_data = (char*)src_block + offset; - char *dest_data = (char*)*dest_block + offset; + dest_i = 0; + for(src_i = 0; src_i < source->numLayers; ++src_i) { + if(source->layers[src_i].flag & LAYERFLAG_NOCOPY) continue; - type_info = layerType_getInfo(data->layers[i].type); + /* find the first dest layer with type >= the source type + * (this should work because layers are ordered by type) + */ + while(dest_i < dest->numLayers + && dest->layers[dest_i].type < source->layers[src_i].type) + ++dest_i; - if(type_info->copy) - type_info->copy(src_data, dest_data, 1, type_info->size); - else - memcpy(dest_data, src_data, type_info->size); + /* if there are no more dest layers, we're done */ + if(dest_i >= dest->numLayers) return 1; + + /* if we found a matching layer, copy the data */ + if(dest->layers[dest_i].type == source->layers[src_i].type) { + char *src_data = (char*)src_block + source->layers[src_i].offset; + char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset; + + type_info = layerType_getInfo(source->layers[src_i].type); + + if(type_info->copy) + type_info->copy(src_data, dest_data, 1, type_info->size); + else + memcpy(dest_data, src_data, type_info->size); + + /* if there are multiple source & dest layers of the same type, + * we don't want to copy all source layers to the same dest, so + * increment dest_i + */ + ++dest_i; + } } return 1; diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index 25559043bc8..d39cd748fb1 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -68,13 +68,13 @@ typedef struct EditVert f1 and f2 can be used for temp data, clear them first*/ unsigned char f, h, f1, f2; short fast; /* only 0 or 1, for editmesh_fastmalloc, do not store temp data here! */ - short totweight; /* __NLA total number of vertex weights for this vertex */ int hash; - struct MDeformWeight *dw; /* __NLA a pointer to an array of defirm weights */ int keyindex; /* original index #, for restoring key information */ /*#ifdef WITH_VERSE*/ void *vvert; /*#endif*/ + + void *data; /* custom vertex data */ } EditVert; struct EditEdge; @@ -168,7 +168,7 @@ typedef struct EditMesh char retopo_mode; /* 0=OFF, 1=ON, 2=PAINT */ struct RetopoPaintData *retopo_paint_data; - CustomData fdata; + CustomData vdata, fdata; #ifdef WITH_VERSE void *vnode; diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index ef568b9d84f..d08c6a39d7d 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -43,6 +43,7 @@ struct Mesh; struct bDeformGroup; struct View3D; struct EditSelection; +struct CustomData; // edge and face flag both #define EM_FGON 2 @@ -104,10 +105,15 @@ extern int faceselectedAND(struct EditFace *efa, int flag); extern void recalc_editnormals(void); extern void flip_editnormals(void); +extern void EM_data_interp_from_verts(struct EditVert *v1, + struct EditVert *v2, struct EditVert *eve, float fac); extern struct EditFace *EM_face_from_faces(struct EditFace *efa1, struct EditFace *efa2, int i1, int i2, int i3, int i4); -extern void EM_interp_from_faces(struct EditFace *efa1, struct EditFace *efa2, - struct EditFace *efan, int i1, int i2, int i3, int i4); +extern void EM_data_interp_from_faces(struct EditFace *efa1, + struct EditFace *efa2, struct EditFace *efan, int i1, int i2, int i3, int i4); + +void EM_add_data_layer(struct CustomData *data, int type); +void EM_free_data_layer(struct CustomData *data, int type); /* ******************* editmesh_mods.c */ diff --git a/source/blender/include/editmesh.h b/source/blender/include/editmesh.h index fc498fd662f..2deab0a6f22 100644 --- a/source/blender/include/editmesh.h +++ b/source/blender/include/editmesh.h @@ -53,7 +53,7 @@ extern void free_facelist(ListBase *lb); extern void remedge(EditEdge *eed); -extern struct EditVert *addvertlist(float *vec); +extern struct EditVert *addvertlist(float *vec, struct EditVert *example); extern struct EditEdge *addedgelist(struct EditVert *v1, struct EditVert *v2, struct EditEdge *example); extern struct EditFace *addfacelist(struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges); extern struct EditEdge *findedgelist(struct EditVert *v1, struct EditVert *v2); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 07c02e279d2..0d9a32d26bd 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3532,9 +3532,14 @@ void do_meshbuts(unsigned short event) break; case B_MAKEVERTCOL: - make_vertexcol(); + if(G.obedit) + EM_add_data_layer(&G.editMesh->fdata, LAYERTYPE_MCOL); + else + make_vertexcol(); break; case B_DELVERTCOL: + if(G.obedit) + EM_free_data_layer(&G.editMesh->fdata, LAYERTYPE_MCOL); if(me->mcol) MEM_freeN(me->mcol); me->mcol= NULL; G.f &= ~G_VERTEXPAINT; @@ -3544,11 +3549,16 @@ void do_meshbuts(unsigned short event) break; case B_MAKE_TFACES: - make_tfaces(me); + if(G.obedit) + EM_add_data_layer(&G.editMesh->fdata, LAYERTYPE_TFACE); + else + make_tfaces(me); allqueue(REDRAWBUTSEDIT, 0); break; case B_DEL_TFACES: + if(G.obedit) + EM_free_data_layer(&G.editMesh->fdata, LAYERTYPE_TFACE); if(me->tface) MEM_freeN(me->tface); me->tface= 0; G.f &= ~G_FACESELECT; diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 1c174e8a0a7..de334b1517f 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -81,6 +81,7 @@ #include "BKE_anim.h" #include "BKE_constraint.h" #include "BKE_curve.h" +#include "BKE_customdata.h" #include "BKE_displist.h" #include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" @@ -1536,6 +1537,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) EditMesh *em = G.editMesh; EditVert *eve, *evedef=NULL; EditEdge *eed; + MDeformVert *dvert; float median[5]; int tot, totw, totweight, totedge; char defstr[320]; @@ -1562,28 +1564,30 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) } eed= eed->next; } + /* check for defgroups */ - if(tot==1 && evedef->totweight) { + dvert= CustomData_em_get(&em->vdata, evedef->data, LAYERTYPE_MDEFORMVERT); + if(tot==1 && dvert->totweight) { bDeformGroup *dg; int i, max=1, init=1; char str[32]; - for (i=0; i<evedef->totweight; i++){ - dg = BLI_findlink (&ob->defbase, evedef->dw[i].def_nr); + for (i=0; i<dvert->totweight; i++){ + dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); if(dg) { - max+= sprintf(str, "%s %%x%d|", dg->name, evedef->dw[i].def_nr); + max+= sprintf(str, "%s %%x%d|", dg->name, dvert->dw[i].def_nr); if(max<320) strcat(defstr, str); } else printf("oh no!\n"); - if(curdef==evedef->dw[i].def_nr) { + if(curdef==dvert->dw[i].def_nr) { init= 0; - defweightp= &evedef->dw[i].weight; + defweightp= &dvert->dw[i].weight; } } if(init) { // needs new initialized - curdef= evedef->dw[0].def_nr; - defweightp= &evedef->dw[0].weight; + curdef= dvert->dw[0].def_nr; + defweightp= &dvert->dw[0].weight; } } } diff --git a/source/blender/src/editdeform.c b/source/blender/src/editdeform.c index 62128be9a73..cea223f98df 100644 --- a/source/blender/src/editdeform.c +++ b/source/blender/src/editdeform.c @@ -45,6 +45,7 @@ #include "BLI_blenlib.h" #include "BLI_editVert.h" +#include "BKE_customdata.h" #include "BKE_DerivedMesh.h" #include "BKE_depsgraph.h" #include "BKE_deform.h" @@ -70,6 +71,7 @@ void sel_verts_defgroup (int select) EditVert *eve; Object *ob; int i; + MDeformVert *dvert; ob= G.obedit; @@ -79,9 +81,11 @@ void sel_verts_defgroup (int select) switch (ob->type){ case OB_MESH: for (eve=G.editMesh->verts.first; eve; eve=eve->next){ - if (eve->totweight){ - for (i=0; i<eve->totweight; i++){ - if (eve->dw[i].def_nr == (ob->actdef-1)){ + dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, LAYERTYPE_MDEFORMVERT); + + if (dvert && dvert->totweight){ + for (i=0; i<dvert->totweight; i++){ + if (dvert->dw[i].def_nr == (ob->actdef-1)){ if (select) eve->f |= SELECT; else eve->f &= ~SELECT; @@ -98,9 +102,10 @@ void sel_verts_defgroup (int select) case OB_LATTICE: if(editLatt->dvert) { BPoint *bp; - MDeformVert *dvert= editLatt->dvert; int a, tot; + dvert= editLatt->dvert; + tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) { for (i=0; i<dvert->totweight; i++){ @@ -215,12 +220,15 @@ void del_defgroup (Object *ob) if(ob->type==OB_MESH) { EditMesh *em = G.editMesh; EditVert *eve; + MDeformVert *dvert; for (eve=em->verts.first; eve; eve=eve->next){ - for (i=0; i<eve->totweight; i++){ - if (eve->dw[i].def_nr > (ob->actdef-1)) - eve->dw[i].def_nr--; - } + dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, LAYERTYPE_MDEFORMVERT); + + if (dvert) + for (i=0; i<dvert->totweight; i++) + if (dvert->dw[i].def_nr > (ob->actdef-1)) + dvert->dw[i].def_nr--; } } else { @@ -482,6 +490,7 @@ void assign_verts_defgroup (void) EditVert *eve; bDeformGroup *dg, *eg; MDeformWeight *newdw; + MDeformVert *dvert; int i, done; ob= G.obedit; @@ -497,35 +506,40 @@ void assign_verts_defgroup (void) switch (ob->type){ case OB_MESH: + if (!CustomData_has_layer(&G.editMesh->vdata, LAYERTYPE_MDEFORMVERT)) + EM_add_data_layer(&G.editMesh->vdata, LAYERTYPE_MDEFORMVERT); + /* Go through the list of editverts and assign them */ for (eve=G.editMesh->verts.first; eve; eve=eve->next){ - if (eve->f & 1){ + dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, LAYERTYPE_MDEFORMVERT); + + if (dvert && (eve->f & 1)){ done=0; /* See if this vert already has a reference to this group */ /* If so: Change its weight */ done=0; - for (i=0; i<eve->totweight; i++){ - eg = BLI_findlink (&ob->defbase, eve->dw[i].def_nr); + for (i=0; i<dvert->totweight; i++){ + eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); /* Find the actual group */ if (eg==dg){ - eve->dw[i].weight=editbutvweight; + dvert->dw[i].weight=editbutvweight; done=1; break; } } /* If not: Add the group and set its weight */ if (!done){ - newdw = MEM_callocN (sizeof(MDeformWeight)*(eve->totweight+1), "deformWeight"); - if (eve->dw){ - memcpy (newdw, eve->dw, sizeof(MDeformWeight)*eve->totweight); - MEM_freeN (eve->dw); + newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); + if (dvert->dw){ + memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); + MEM_freeN (dvert->dw); } - eve->dw=newdw; + dvert->dw=newdw; - eve->dw[eve->totweight].weight= editbutvweight; - eve->dw[eve->totweight].def_nr= ob->actdef-1; + dvert->dw[dvert->totweight].weight= editbutvweight; + dvert->dw[dvert->totweight].def_nr= ob->actdef-1; - eve->totweight++; + dvert->totweight++; } } @@ -585,6 +599,7 @@ void remove_verts_defgroup (int allverts) { Object *ob; EditVert *eve; + MDeformVert *dvert; MDeformWeight *newdw; bDeformGroup *dg, *eg; int i; @@ -603,25 +618,27 @@ void remove_verts_defgroup (int allverts) switch (ob->type){ case OB_MESH: for (eve=G.editMesh->verts.first; eve; eve=eve->next){ - if (eve->dw && ((eve->f & 1) || allverts)){ - for (i=0; i<eve->totweight; i++){ + dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, LAYERTYPE_MDEFORMVERT); + + if (dvert && dvert->dw && ((eve->f & 1) || allverts)){ + for (i=0; i<dvert->totweight; i++){ /* Find group */ - eg = BLI_findlink (&ob->defbase, eve->dw[i].def_nr); + eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); if (eg == dg){ - eve->totweight--; - if (eve->totweight){ - newdw = MEM_mallocN (sizeof(MDeformWeight)*(eve->totweight), "deformWeight"); + dvert->totweight--; + if (dvert->totweight){ + newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight"); - if (eve->dw){ - memcpy (newdw, eve->dw, sizeof(MDeformWeight)*i); - memcpy (newdw+i, eve->dw+i+1, sizeof(MDeformWeight)*(eve->totweight-i)); - MEM_freeN (eve->dw); + if (dvert->dw){ + memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i); + memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); + MEM_freeN (dvert->dw); } - eve->dw=newdw; + dvert->dw=newdw; } else{ - MEM_freeN (eve->dw); - eve->dw=NULL; + MEM_freeN (dvert->dw); + dvert->dw=NULL; } } } diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index a891fe1adab..34fb0f1d17a 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -134,7 +134,7 @@ static void *(*callocvert)(size_t, size_t) = calloc; static void *(*callocedge)(size_t, size_t) = calloc; static void *(*callocface)(size_t, size_t) = calloc; -EditVert *addvertlist(float *vec) +EditVert *addvertlist(float *vec, EditVert *example) { EditMesh *em = G.editMesh; EditVert *eve; @@ -156,6 +156,11 @@ EditVert *addvertlist(float *vec) createVerseVert(eve); #endif + if(example) + CustomData_em_copy_data(&em->vdata, &em->vdata, example->data, &eve->data); + else + CustomData_em_set_default(&em->vdata, &eve->data); + return eve; } @@ -172,11 +177,10 @@ void free_editvert (EditVert *eve) } #endif - if(eve->dw) MEM_freeN(eve->dw); EM_remove_selection(eve, EDITVERT); - if(eve->fast==0){ + CustomData_em_free_block(&G.editMesh->vdata, &eve->data); + if(eve->fast==0) free(eve); - } } @@ -411,7 +415,7 @@ EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, Ed if(example) { efa->mat_nr= example->mat_nr; efa->flag= example->flag; - CustomData_em_copy_data(&em->fdata, example->data, &efa->data); + CustomData_em_copy_data(&em->fdata, &em->fdata, example->data, &efa->data); } else { if (G.obedit && G.obedit->actcol) @@ -554,6 +558,7 @@ void free_editMesh(EditMesh *em) if(em->faces.first) free_facelist(&em->faces); if(em->selected.first) BLI_freelistN(&(em->selected)); + CustomData_free(&em->vdata); CustomData_free(&em->fdata); if(em->derivedFinal) { @@ -784,7 +789,7 @@ void make_editMesh() EditFace *efa; EditEdge *eed; EditSelection *ese; - CustomData mfdata; + CustomData mvdata, mfdata; int tot, a, eekadoodle= 0; #ifdef WITH_VERSE @@ -817,11 +822,16 @@ void make_editMesh() } /* make editverts */ + CustomData_init(&mvdata, 0, me->totvert, SUB_ELEMS_VERT); + if(me->dvert) + CustomData_add_layer(&mvdata, LAYERTYPE_MDEFORMVERT, LAYERFLAG_NOFREE, me->dvert); + CustomData_from_template(&mvdata, &em->vdata, 0, 0); + mvert= me->mvert; evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist"); for(a=0; a<tot; a++, mvert++) { - eve= addvertlist(mvert->co); + eve= addvertlist(mvert->co, NULL); evlist[a]= eve; // face select sets selection in next loop @@ -839,16 +849,11 @@ void make_editMesh() */ eve->keyindex = a; - if (me->dvert){ - eve->totweight = me->dvert[a].totweight; - if (me->dvert[a].dw){ - eve->dw = MEM_callocN (sizeof(MDeformWeight) * me->dvert[a].totweight, "deformWeight"); - memcpy (eve->dw, me->dvert[a].dw, sizeof(MDeformWeight) * me->dvert[a].totweight); - } - } - + CustomData_to_em_block(&mvdata, &em->vdata, a, &eve->data); } + CustomData_free(&mvdata); + if(actkey && actkey->totelem!=me->totvert); else { MEdge *medge= me->medge; @@ -972,8 +977,7 @@ void load_editMesh(void) EditSelection *ese; float *fp, *newkey, *oldkey, nor[3]; int i, a, ototvert, totedge=0; - MDeformVert *dvert; - CustomData mfdata; + CustomData mvdata, mfdata; #ifdef WITH_VERSE if(em->vnode) { @@ -1010,13 +1014,19 @@ void load_editMesh(void) if(G.totface==0) mface= NULL; else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face"); - /* are we adding dverts? */ - if (G.totvert==0) dvert= NULL; - else if(G.obedit->defbase.first==NULL) dvert= NULL; - else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3"); - - if (me->dvert) free_dverts(me->dvert, me->totvert); - me->dvert=dvert; + /* free vertex and face data */ + if (me->dvert) { + free_dverts(me->dvert, me->totvert); + me->dvert= NULL; + } + if(me->tface) { + MEM_freeN(me->tface); + me->tface = NULL; + } + if(me->mcol) { + MEM_freeN(me->mcol); + me->mcol = NULL; + } /* 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 */ @@ -1036,15 +1046,8 @@ void load_editMesh(void) me->mface= mface; me->totface= G.totface; - /* face data */ - if(me->tface) { - MEM_freeN(me->tface); - me->tface = NULL; - } - if(me->mcol) { - MEM_freeN(me->mcol); - me->mcol = NULL; - } + /* vertex and face data */ + CustomData_from_template(&em->vdata, &mvdata, LAYERFLAG_NOFREE, me->totvert); CustomData_from_template(&em->fdata, &mfdata, LAYERFLAG_NOFREE, me->totface); /* the vertices, use ->tmp.l as counter */ @@ -1060,16 +1063,9 @@ void load_editMesh(void) VecMulf(nor, 32767.0); VECCOPY(mvert->no, nor); - /* note: it used to remove me->dvert when it was not in use, cancelled that... annoying when you have a fresh vgroup */ - 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); - } - } + /* note: it used to remove me->dvert when it was not in use, cancelled + that... annoying when you have a fresh vgroup */ + CustomData_from_em_block(&em->vdata, &mvdata, eve->data, a); eve->tmp.l = a++; /* counter */ @@ -1086,9 +1082,12 @@ void load_editMesh(void) #endif eve= eve->next; mvert++; - if(dvert) dvert++; } + /* from CustomData to dvert in Mesh */ + me->dvert = CustomData_get(&mvdata, 0, LAYERTYPE_MDEFORMVERT); + CustomData_free(&mvdata); + /* the edges */ a= 0; eed= em->edges.first; @@ -1180,14 +1179,14 @@ void load_editMesh(void) /* sync hide and select flags with faceselect mode */ if(G.f & G_FACESELECT) { - if(me->tface && (me->totface > 0)) { + if(CustomData_has_layer(&mfdata, LAYERTYPE_TFACE) && (me->totface > 0)) { efa= em->faces.first; - for(a=0, efa=em->faces.first; efa; a++, efa++) { + for(a=0, efa=em->faces.first; efa; a++, efa=efa->next) { tf = CustomData_get(&mfdata, a, LAYERTYPE_TFACE); if(efa->h) tf->flag |= TF_HIDE; else tf->flag &= ~TF_HIDE; - if(efa->f & SELECT) tf->flag |= TF_SELECT; + if(efa->f & SELECT) tf->flag |= TF_SELECT; else tf->flag &= ~TF_SELECT; } } @@ -1196,7 +1195,6 @@ void load_editMesh(void) /* from CustomData to tface and mcol in Mesh */ me->tface = CustomData_get(&mfdata, 0, LAYERTYPE_TFACE); me->mcol = CustomData_get(&mfdata, 0, LAYERTYPE_MCOL); - CustomData_free(&mfdata); /* patch hook indices */ @@ -1566,6 +1564,7 @@ void separate_mesh(void) emcopy.alledges= NULL; emcopy.allfaces= NULL; emcopy.derivedFinal= emcopy.derivedCage= NULL; + memset(&emcopy.vdata, 0, sizeof(emcopy.vdata)); memset(&emcopy.fdata, 0, sizeof(emcopy.fdata)); free_editMesh(&emcopy); @@ -1760,6 +1759,7 @@ void separate_mesh_loose(void) emcopy.alledges= NULL; emcopy.allfaces= NULL; emcopy.derivedFinal= emcopy.derivedCage= NULL; + memset(&emcopy.vdata, 0, sizeof(emcopy.vdata)); memset(&emcopy.fdata, 0, sizeof(emcopy.fdata)); free_editMesh(&emcopy); @@ -1801,8 +1801,6 @@ typedef struct EditVertC float no[3]; float co[3]; unsigned char f, h; - short totweight; - struct MDeformWeight *dw; int keyindex; } EditVertC; @@ -1835,7 +1833,7 @@ typedef struct UndoMesh { short selectmode; RetopoPaintData *retopo_paint_data; char retopo_mode; - CustomData fdata; + CustomData vdata, fdata; } UndoMesh; /* for callbacks */ @@ -1843,18 +1841,13 @@ typedef struct UndoMesh { static void free_undoMesh(void *umv) { UndoMesh *um= umv; - EditVertC *evec; - int a; - - for(a=0, evec= um->verts; a<um->totvert; a++, evec++) { - if(evec->dw) MEM_freeN(evec->dw); - } if(um->verts) MEM_freeN(um->verts); if(um->edges) MEM_freeN(um->edges); if(um->faces) MEM_freeN(um->faces); if(um->selected) MEM_freeN(um->selected); if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data); + CustomData_free(&um->vdata); CustomData_free(&um->fdata); MEM_freeN(um); } @@ -1888,6 +1881,7 @@ static void *editMesh_to_undoMesh(void) if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC"); if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections"); + if(um->totvert) CustomData_from_template(&em->vdata, &um->vdata, 0, um->totvert); if(um->totface) CustomData_from_template(&em->fdata, &um->fdata, 0, um->totface); /* now copy vertices */ @@ -1899,9 +1893,9 @@ static void *editMesh_to_undoMesh(void) evec->f= eve->f; evec->h= eve->h; evec->keyindex= eve->keyindex; - evec->totweight= eve->totweight; - evec->dw= MEM_dupallocN(eve->dw); eve->tmp.l = a; /*store index*/ + + CustomData_from_em_block(&em->vdata, &um->vdata, eve->data, a); } /* copy edges */ @@ -1988,17 +1982,20 @@ static void undoMesh_to_editMesh(void *umv) #endif /* now copy vertices */ + CustomData_free(&em->vdata); + CustomData_from_template(&um->vdata, &em->vdata, 0, 0); + if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar"); for(a=0, evec= um->verts; a<um->totvert; a++, evec++) { - eve= addvertlist(evec->co); + eve= addvertlist(evec->co, NULL); evar[a]= eve; VECCOPY(eve->no, evec->no); eve->f= evec->f; eve->h= evec->h; - eve->totweight= evec->totweight; eve->keyindex= evec->keyindex; - eve->dw= MEM_dupallocN(evec->dw); + + CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data); } /* copy edges */ diff --git a/source/blender/src/editmesh_add.c b/source/blender/src/editmesh_add.c index 9347d7f4793..d1ea36520d8 100644 --- a/source/blender/src/editmesh_add.c +++ b/source/blender/src/editmesh_add.c @@ -228,7 +228,7 @@ void add_click_mesh(void) float mat[3][3],imat[3][3]; float *curs= give_cursor(); - eve= addvertlist(0); + eve= addvertlist(0, NULL); Mat3CpyMat4(mat, G.obedit->obmat); Mat3Inv(imat, mat); @@ -837,7 +837,7 @@ void make_prim(int type, float imat[3][3], short tot, short seg, vec[1]= cent[1]- dia; vec[2]= cent[2]; Mat3MulVecfl(imat,vec); - eve= addvertlist(vec); + eve= addvertlist(vec, NULL); eve->f= 1+2+4; if (a) { addedgelist(eve->prev, eve, NULL); @@ -869,7 +869,7 @@ void make_prim(int type, float imat[3][3], short tot, short seg, vec[0]= dia*sin(phi); vec[1]= 0.0; vec[2]= dia*cos(phi); - eve= addvertlist(vec); + eve= addvertlist(vec, NULL); eve->f= 1+2+4; if(a==0) v1= eve; else addedgelist(eve->prev, eve, NULL); @@ -916,7 +916,7 @@ void make_prim(int type, float imat[3][3], short tot, short seg, vec[0]= dia*icovert[a][0]; vec[1]= dia*icovert[a][1]; vec[2]= dia*icovert[a][2]; - eva[a]= addvertlist(vec); + eva[a]= addvertlist(vec, NULL); eva[a]->f= 1+2; } for(a=0;a<20;a++) { @@ -962,9 +962,9 @@ void make_prim(int type, float imat[3][3], short tot, short seg, for (i=0; i<monkeynv; i++) { float v[3]; v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0; - tv[i]= addvertlist(v); + tv[i]= addvertlist(v, NULL); tv[i]->f |= SELECT; - tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v); + tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v, NULL); tv[monkeynv+i]->f |= SELECT; } for (i=0; i<monkeynf; i++) { @@ -997,7 +997,7 @@ void make_prim(int type, float imat[3][3], short tot, short seg, vec[2]= cent[2]+d; Mat3MulVecfl(imat, vec); - eve= addvertlist(vec); + eve= addvertlist(vec, NULL); eve->f= SELECT; if(a==0) { if(b==0) v1= eve; @@ -1012,12 +1012,12 @@ void make_prim(int type, float imat[3][3], short tot, short seg, VECCOPY(vec,cent); vec[2]-= -d; Mat3MulVecfl(imat,vec); - vdown= addvertlist(vec); + vdown= addvertlist(vec, NULL); if(ext || type==7) { VECCOPY(vec,cent); vec[2]-= d; Mat3MulVecfl(imat,vec); - vtop= addvertlist(vec); + vtop= addvertlist(vec, NULL); } } else { vdown= v1; diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c index ca03dcef555..d40ab35a4db 100644 --- a/source/blender/src/editmesh_lib.c +++ b/source/blender/src/editmesh_lib.c @@ -709,26 +709,44 @@ void EM_hide_reset(void) } -void EM_interp_from_faces(EditFace *efa1, EditFace *efa2, EditFace *efan, int i1, int i2, int i3, int i4) +void EM_data_interp_from_verts(EditVert *v1, EditVert *v2, EditVert *eve, float fac) +{ + EditMesh *em= G.editMesh; + void *src[2]; + float w[2]; + + if (v1->data && v2->data) { + src[0]= v1->data; + src[1]= v2->data; + w[0] = 1.0f-fac; + w[1] = fac; + + CustomData_em_interp(&em->vdata, src, w, NULL, 2, eve->data); + } +} + +void EM_data_interp_from_faces(EditFace *efa1, EditFace *efa2, EditFace *efan, int i1, int i2, int i3, int i4) { EditMesh *em= G.editMesh; float w[2][4][4]; void *src[2]; int count = (efa2)? 2: 1; - /* set weights for copying from corners directly to other corners */ - memset(w, 0, sizeof(w)); + if (efa1->data) { + /* set weights for copying from corners directly to other corners */ + memset(w, 0, sizeof(w)); - w[i1/4][0][i1%4]= 1.0f; - w[i2/4][1][i2%4]= 1.0f; - w[i3/4][2][i3%4]= 1.0f; - if (i4 != -1) - w[i4/4][3][i4%4]= 1.0f; + w[i1/4][0][i1%4]= 1.0f; + w[i2/4][1][i2%4]= 1.0f; + w[i3/4][2][i3%4]= 1.0f; + if (i4 != -1) + w[i4/4][3][i4%4]= 1.0f; - src[0]= efa1->data; - src[1]= (efa2)? efa2->data: NULL; + src[0]= efa1->data; + src[1]= (efa2)? efa2->data: NULL; - CustomData_em_interp(&em->fdata, src, NULL, (float*)w, count, efan->data); + CustomData_em_interp(&em->fdata, src, NULL, (float*)w, count, efan->data); + } } EditFace *EM_face_from_faces(EditFace *efa1, EditFace *efa2, int i1, int i2, int i3, int i4) @@ -742,12 +760,66 @@ EditFace *EM_face_from_faces(EditFace *efa1, EditFace *efa2, int i1, int i2, int efan= addfacelist(v[i1/4][i1%4], v[i2/4][i2%4], v[i3/4][i3%4], (i4 == -1)? 0: v[i4/4][i4%4], efa1, NULL); - if (efa1->data) - EM_interp_from_faces(efa1, efa2, efan, i1, i2, i3, i4); + EM_data_interp_from_faces(efa1, efa2, efan, i1, i2, i3, i4); return efan; } +static void update_data_blocks(CustomData *olddata, CustomData *data) +{ + EditMesh *em= G.editMesh; + EditFace *efa; + EditVert *eve; + void *block; + + if (data == &G.editMesh->vdata) { + for(eve= em->verts.first; eve; eve= eve->next) { + block = NULL; + CustomData_em_copy_data(olddata, data, eve->data, &block); + CustomData_em_free_block(olddata, &eve->data); + eve->data= block; + } + } + else if (data == &G.editMesh->fdata) { + for(efa= em->faces.first; efa; efa= efa->next) { + block = NULL; + CustomData_em_copy_data(olddata, data, efa->data, &block); + CustomData_em_free_block(olddata, &efa->data); + efa->data= block; + } + } +} + +void EM_add_data_layer(CustomData *data, int type) +{ + CustomData olddata; + + if (CustomData_has_layer(data, type)) + return; + + olddata= *data; + olddata.layers= MEM_dupallocN(olddata.layers); + CustomData_add_layer(data, type, 0, NULL); + + update_data_blocks(&olddata, data); + MEM_freeN(olddata.layers); +} + +void EM_free_data_layer(CustomData *data, int type) +{ + CustomData olddata; + + if (!CustomData_has_layer(data, type)) + return; + + olddata= *data; + olddata.layers= MEM_dupallocN(olddata.layers); + CustomData_free_layer(data, type); + + update_data_blocks(&olddata, data); + MEM_freeN(olddata.layers); +} + /* ******** EXTRUDE ********* */ static void add_normal_aligned(float *nor, float *add) @@ -843,34 +915,16 @@ short extrudeflag_face_indiv(short flag, float *nor) /* step 2: make new faces from faces */ for(efa= em->faces.last; efa; efa= efa->prev) { if(efa->f & SELECT) { - v1= addvertlist(efa->v1->co); - if(efa->v1->totweight){ - v1->dw = MEM_dupallocN(efa->v1->dw); - v1->totweight = efa->v1->totweight; - } - - v2= addvertlist(efa->v2->co); - if(efa->v2->totweight){ - v2->dw = MEM_dupallocN(efa->v2->dw); - v2->totweight = efa->v2->totweight; - } - - v3= addvertlist(efa->v3->co); - if(efa->v3->totweight){ - v3->dw = MEM_dupallocN(efa->v3->dw); - v3->totweight = efa->v3->totweight; - } + v1= addvertlist(efa->v1->co, efa->v1); + v2= addvertlist(efa->v2->co, efa->v2); + v3= addvertlist(efa->v3->co, efa->v3); v1->f1= v2->f1= v3->f1= 1; VECCOPY(v1->no, efa->n); VECCOPY(v2->no, efa->n); VECCOPY(v3->no, efa->n); if(efa->v4) { - v4= addvertlist(efa->v4->co); - if(efa->v4->totweight){ - v4->dw = MEM_dupallocN(efa->v4->dw); - v4->totweight = efa->v4->totweight; - } + v4= addvertlist(efa->v4->co, efa->v4); v4->f1= 1; VECCOPY(v4->no, efa->n); } @@ -942,20 +996,11 @@ short extrudeflag_edges_indiv(short flag, float *nor) /* make the faces */ for(eed= em->edges.first; eed; eed= eed->next) { if(eed->f & flag) { - if(eed->v1->tmp.v == NULL){ - eed->v1->tmp.v = addvertlist(eed->v1->co); - if(eed->v1->totweight){ - eed->v1->tmp.v->dw = MEM_dupallocN(eed->v1->dw); - eed->v1->tmp.v->totweight = eed->v1->totweight; - } - } - if(eed->v2->tmp.v == NULL){ - eed->v2->tmp.v = addvertlist(eed->v2->co); - if(eed->v2->totweight){ - eed->v2->tmp.v->dw = MEM_dupallocN(eed->v2->dw); - eed->v2->tmp.v->totweight = eed->v2->totweight; - } - } + if(eed->v1->tmp.v == NULL) + eed->v1->tmp.v = addvertlist(eed->v1->co, eed->v1); + if(eed->v2->tmp.v == NULL) + eed->v2->tmp.v = addvertlist(eed->v2->co, eed->v2); + if(eed->dir==1) addfacelist(eed->v1, eed->v2, eed->v2->tmp.v, eed->v1->tmp.v, @@ -999,11 +1044,7 @@ short extrudeflag_verts_indiv(short flag, float *nor) /* make the edges */ for(eve= em->verts.first; eve; eve= eve->next) { if(eve->f & flag) { - eve->tmp.v = addvertlist(eve->co); - if(eve->totweight){ - eve->tmp.v->dw = MEM_dupallocN(eve->dw); - eve->tmp.v->totweight = eve->totweight; - } + eve->tmp.v = addvertlist(eve->co, eve); addedgelist(eve, eve->tmp.v, NULL); } else eve->tmp.v = NULL; @@ -1136,20 +1177,11 @@ static short extrudeflag_edge(short flag, float *nor) for(eed= em->edges.last; eed; eed= eed->prev) { if(eed->f & SELECT) { if(eed->f2<2) { - if(eed->v1->tmp.v == NULL){ - eed->v1->tmp.v = addvertlist(eed->v1->co); - if(eed->v1->totweight){ - eed->v1->tmp.v->dw = MEM_dupallocN(eed->v1->dw); - eed->v1->tmp.v->totweight = eed->v1->totweight; - } - } - if(eed->v2->tmp.v == NULL){ - eed->v2->tmp.v = addvertlist(eed->v2->co); - if(eed->v2->totweight){ - eed->v2->tmp.v->dw = MEM_dupallocN(eed->v2->dw); - eed->v2->tmp.v->totweight = eed->v2->totweight; - } - } + if(eed->v1->tmp.v == NULL) + eed->v1->tmp.v = addvertlist(eed->v1->co, eed->v1); + if(eed->v2->tmp.v == NULL) + eed->v2->tmp.v = addvertlist(eed->v2->co, eed->v2); + /* if del_old, the preferred normal direction is exact * opposite as for keep old faces */ @@ -1168,34 +1200,14 @@ static short extrudeflag_edge(short flag, float *nor) /* step 3: make new faces from faces */ for(efa= em->faces.last; efa; efa= efa->prev) { if(efa->f & SELECT) { - if (efa->v1->tmp.v == NULL){ - efa->v1->tmp.v = addvertlist(efa->v1->co); - if(efa->v1->totweight){ - efa->v1->tmp.v->dw = MEM_dupallocN(efa->v1->dw); - efa->v1->tmp.v->totweight = efa->v1->totweight; - } - } - if (efa->v2->tmp.v ==NULL){ - efa->v2->tmp.v = addvertlist(efa->v2->co); - if(efa->v2->totweight){ - efa->v2->tmp.v->dw = MEM_dupallocN(efa->v2->dw); - efa->v2->tmp.v->totweight = efa->v2->totweight; - } - } - if (efa->v3->tmp.v ==NULL){ - efa->v3->tmp.v = addvertlist(efa->v3->co); - if(efa->v3->totweight){ - efa->v3->tmp.v->dw = MEM_dupallocN(efa->v3->dw); - efa->v3->tmp.v->totweight = efa->v3->totweight; - } - } - if (efa->v4 && (efa->v4->tmp.v == NULL)){ - efa->v4->tmp.v = addvertlist(efa->v4->co); - if(efa->v4->totweight){ - efa->v4->tmp.v->dw = MEM_dupallocN(efa->v4->dw); - efa->v4->tmp.v->totweight = efa->v4->totweight; - } - } + if (efa->v1->tmp.v == NULL) + efa->v1->tmp.v = addvertlist(efa->v1->co, efa->v1); + if (efa->v2->tmp.v ==NULL) + efa->v2->tmp.v = addvertlist(efa->v2->co, efa->v2); + if (efa->v3->tmp.v ==NULL) + efa->v3->tmp.v = addvertlist(efa->v3->co, efa->v3); + if (efa->v4 && (efa->v4->tmp.v == NULL)) + efa->v4->tmp.v = addvertlist(efa->v4->co, efa->v4); if(del_old==0) { // keep old faces means flipping normal if(efa->v4) @@ -1425,7 +1437,7 @@ short extrudeflag_vert(short flag, float *nor) eve->f &= ~128; /* clear, for later test for loose verts */ if(eve->f & flag) { sel= 1; - v1= addvertlist(0); + v1= addvertlist(0, NULL); VECCOPY(v1->co, eve->co); v1->f= eve->f; @@ -1482,7 +1494,7 @@ short extrudeflag_vert(short flag, float *nor) efa = eed->tmp.f; efa2->mat_nr= efa->mat_nr; efa2->flag= efa->flag; - CustomData_em_copy_data(&em->fdata, &efa->data, &efa2->data); + CustomData_em_copy_data(&em->fdata, &em->fdata, &efa->data, &efa2->data); } /* Needs smarter adaption of existing creases. @@ -1621,7 +1633,8 @@ void translateflag(short flag, float *vec) /* helper call for below */ static EditVert *adduplicate_vertex(EditVert *eve, int flag) { - EditVert *v1= addvertlist(eve->co); + /* FIXME: copy deformation weight from eve ok here? */ + EditVert *v1= addvertlist(eve->co, eve); v1->f= eve->f; eve->f-= flag; @@ -1629,15 +1642,6 @@ static EditVert *adduplicate_vertex(EditVert *eve, int flag) eve->tmp.v = v1; - /* FIXME: Copy deformation weight ? */ - v1->totweight = eve->totweight; - if (eve->totweight){ - v1->dw = MEM_mallocN (eve->totweight * sizeof(MDeformWeight), "deformWeight"); - memcpy (v1->dw, eve->dw, eve->totweight * sizeof(MDeformWeight)); - } - else - v1->dw=NULL; - return v1; } @@ -1800,13 +1804,13 @@ void flipface(EditFace *efa) SWAP(EditVert *, efa->v2, efa->v4); SWAP(EditEdge *, efa->e1, efa->e4); SWAP(EditEdge *, efa->e2, efa->e3); - EM_interp_from_faces(efa, NULL, efa, 0, 3, 2, 1); + EM_data_interp_from_faces(efa, NULL, efa, 0, 3, 2, 1); } else { SWAP(EditVert *, efa->v2, efa->v3); SWAP(EditEdge *, efa->e1, efa->e3); efa->e2->dir= 1-efa->e2->dir; - EM_interp_from_faces(efa, NULL, efa, 0, 2, 1, 3); + EM_data_interp_from_faces(efa, NULL, efa, 0, 2, 1, 3); } if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n); diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index c5958be912b..52befe8a64c 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -1167,20 +1167,26 @@ int vertgroup_select(short mode) return selcount; } } - } else if (mode==3 && base_eve->totweight != 0) { /* vertex groups */ - short i,j; /*weight index*/ + } else if (mode==3) { /* vertex groups */ + MDeformVert *dvert, *base_dvert; + short i, j; /* weight index */ + + base_dvert= CustomData_em_get(&em->vdata, base_eve->data, + LAYERTYPE_MDEFORMVERT); + + if (!base_dvert || base_dvert->totweight == 0) + return selcount; for(eve= em->verts.first; eve; eve= eve->next) { - if ( - !(eve->f & SELECT) && - !eve->h && - eve->totweight - ) { + dvert= CustomData_em_get(&em->vdata, eve->data, + LAYERTYPE_MDEFORMVERT); + + if (dvert && !(eve->f & SELECT) && !eve->h && dvert->totweight) { /* do the extra check for selection in the following if, so were not checking verts that may be alredy selected */ - for (i=0; base_eve->totweight >i && !(eve->f & SELECT); i++) { - for (j=0; eve->totweight >j; j++) { - if (base_eve->dw[i].def_nr==eve->dw[j].def_nr) { + for (i=0; base_dvert->totweight >i && !(eve->f & SELECT); i++) { + for (j=0; dvert->totweight >j; j++) { + if (base_dvert->dw[i].def_nr==dvert->dw[j].def_nr) { eve->f |= SELECT; selcount++; deselcount--; diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index 2d10f93ef1c..8b7bf72b434 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -203,8 +203,7 @@ int removedoublesflag(short flag, float limit) /* return amount */ xvertsort *sortblock, *sb, *sb1; struct facesort *vlsortblock, *vsb, *vsb1; float dist; - int a, b, test, amount, currweight, doubweight, targetweight; - MDeformWeight *newdw; + int a, b, test, amount; /* flag 128 is cleared, count */ eve= em->verts.first; @@ -263,50 +262,9 @@ int removedoublesflag(short flag, float limit) /* return amount */ } MEM_freeN(sortblock); - - for(eve = em->verts.first; eve; eve=eve->next){ - - if(eve->f & flag) { - if(eve->f & 128) { - - v1 = eve->tmp.v; - - - if(v1->dw && eve->dw){ - for(doubweight=0; doubweight < eve->totweight; doubweight++){ - targetweight = -1; - for(currweight = 0; currweight < v1->totweight; currweight++){ - if(v1->dw[currweight].def_nr == eve->dw[doubweight].def_nr){ - targetweight = currweight; - break; - } - } - - if(targetweight != -1){ /*average*/ - v1->dw[targetweight].weight = (v1->dw[targetweight].weight + eve->dw[doubweight].weight) / 2; - } - else{ /*append*/ - newdw = MEM_callocN(sizeof(MDeformWeight)*(v1->totweight+1), "MDeformWeight Append"); - memcpy(newdw, v1->dw, sizeof(MDeformWeight)*v1->totweight); - MEM_freeN(v1->dw); - - v1->dw= newdw; - v1->dw[v1->totweight].weight = eve->dw[doubweight].weight; - v1->dw[v1->totweight].def_nr = eve->dw[doubweight].def_nr; - v1->totweight++; - } - } - } - else if(eve->dw){ /*just straight copy vert weights*/ - - newdw = MEM_mallocN(sizeof(MDeformWeight) * (eve->totweight), "MDeformWeight Copy"); - memcpy(newdw, eve->dw, sizeof(MDeformWeight)*eve->totweight); - v1->dw= newdw; - - } - } - } - } + for(eve = em->verts.first; eve; eve=eve->next) + if((eve->f & flag) && (eve->f & 128)) + EM_data_interp_from_verts(eve, eve->tmp.v, eve->tmp.v, 0.5f); /* test edges and insert again */ eed= em->edges.first; @@ -373,7 +331,7 @@ int removedoublesflag(short flag, float limit) /* return amount */ efa->v3= efa->v4; efa->v4= 0; - EM_interp_from_faces(efa, NULL, efa, 0, 2, 3, 3); + EM_data_interp_from_faces(efa, NULL, efa, 0, 2, 3, 3); test= 0; } @@ -1208,59 +1166,6 @@ void fill_mesh(void) /*used by faceloop cut to select only edges valid for edge slide*/ #define DOUBLEOPFILL 16 -/* Mostly mirrored from editdeform.c, here only used for the function below */ -/* Only to be used to add new weights in eve, the value of weight has been premultiplied with subdiv factor, so is added only */ -static void subdiv_add_defweight (EditVert *eve, int defgroup, float weight) -{ - MDeformWeight *newdw; - int i; - - if (defgroup<0) - return; - - for (i=0; i<eve->totweight; i++) { - if (eve->dw[i].def_nr == defgroup) { - eve->dw[i].weight += weight; - return; - } - } - - newdw = MEM_callocN (sizeof(MDeformWeight)*(eve->totweight+1), "subdiv deformWeight"); - if (eve->dw) { - memcpy (newdw, eve->dw, sizeof(MDeformWeight)*eve->totweight); - MEM_freeN (eve->dw); - } - eve->dw= newdw; - - eve->dw[eve->totweight].weight= weight; - eve->dw[eve->totweight].def_nr= defgroup; - - eve->totweight++; - -} - - -/* the new vertex *eve will get vertex groups as defined in eed, based on fac subdivide */ -static void subdivide_edge_vgroups(EditEdge *eed, EditVert *eve, float fac) -{ - EditVert *v1= eed->v1, *v2= eed->v2; - int i; - - /* let's first check of there are groups */ - if(v1->totweight==0 && v2->totweight==0) - return; - - /* now add the weights of v1 into the new vertex */ - for (i=0; i<v1->totweight; i++) { - subdiv_add_defweight(eve, v1->dw[i].def_nr, v1->dw[i].weight*(1.0f-fac)); - } - - /* now add the weights of v2 into the new vertex */ - for (i=0; i<v2->totweight; i++) { - subdiv_add_defweight(eve, v2->dw[i].def_nr, v2->dw[i].weight*fac); - } -} - /* calculates offset for co, based on fractal, sphere or smooth settings */ static void alter_co(float *co, EditEdge *edge, float rad, int beauty, float perc) { @@ -1331,10 +1236,10 @@ static EditVert *subdivide_edge_addvert(EditEdge *edge, float rad, int beauty, f /* offset for smooth or sphere or fractal */ alter_co(co, edge, rad, beauty, percent); - ev = addvertlist(co); + ev = addvertlist(co, NULL); - /* vgroups */ - subdivide_edge_vgroups(edge, ev, percent); + /* vert data (vgroups, ..) */ + EM_data_interp_from_verts(edge->v1, edge->v2, ev, percent); /* normal */ ev->no[0] = (edge->v2->no[0]-edge->v1->no[0])*percent + edge->v1->no[0]; @@ -1393,11 +1298,12 @@ void interp_uv_vcol(float *v1, float *v2, float *v3, float *v4, float *co, TFace static void facecopy(EditFace *source, EditFace *target) { + EditMesh *em= G.editMesh; float *v1 = source->v1->co, *v2 = source->v2->co, *v3 = source->v3->co; float *v4 = source->v4? source->v4->co: NULL; float w[4][4]; - CustomData_em_copy_data(&G.editMesh->fdata, source->data, &target->data); + CustomData_em_copy_data(&em->fdata, &em->fdata, source->data, &target->data); target->mat_nr = source->mat_nr; target->flag = source->flag; @@ -1408,8 +1314,7 @@ static void facecopy(EditFace *source, EditFace *target) if (target->v4) InterpWeightsQ3Dfl(v1, v2, v3, v4, target->v4->co, w[3]); - CustomData_em_interp(&G.editMesh->fdata, &source->data, NULL, - (float*)w, 1, target->data); + CustomData_em_interp(&em->fdata, &source->data, NULL, (float*)w, 1, target->data); } static void fill_quad_single(EditFace *efa, struct GHash *gh, int numcuts, int seltype) @@ -1831,11 +1736,13 @@ static void fill_quad_double_adj_inner(EditFace *efa, struct GHash *gh, int numc inner = MEM_mallocN(sizeof(EditVert*)*numcuts,"New inner verts"); for(i=0;i<numcuts;i++) { - co[0] = (verts[0][numcuts-i]->co[0] + verts[1][i+1]->co[0] ) / 2 ; - co[1] = (verts[0][numcuts-i]->co[1] + verts[1][i+1]->co[1] ) / 2 ; - co[2] = (verts[0][numcuts-i]->co[2] + verts[1][i+1]->co[2] ) / 2 ; - inner[i] = addvertlist(co); - inner[i]->f2 |= EDGEINNER; + co[0] = (verts[0][numcuts-i]->co[0] + verts[1][i+1]->co[0] ) / 2 ; + co[1] = (verts[0][numcuts-i]->co[1] + verts[1][i+1]->co[1] ) / 2 ; + co[2] = (verts[0][numcuts-i]->co[2] + verts[1][i+1]->co[2] ) / 2 ; + inner[i] = addvertlist(co, NULL); + inner[i]->f2 |= EDGEINNER; + + EM_data_interp_from_verts(verts[0][numcuts-i], verts[1][i+1], inner[i], 0.5f); } // Add Corner Quad @@ -4299,55 +4206,22 @@ static void bevel_mesh(float bsize, int allfaces) while (efa) { if (efa->f1 & 1) { efa->f1-= 1; - v1= addvertlist(efa->v1->co); + v1= addvertlist(efa->v1->co, efa->v1); v1->f= efa->v1->f & ~128; efa->v1->tmp.v = v1; -#ifdef __NLA - v1->totweight = efa->v1->totweight; - if (efa->v1->totweight) { - v1->dw = MEM_mallocN (efa->v1->totweight * sizeof(MDeformWeight), "deformWeight"); - memcpy (v1->dw, efa->v1->dw, efa->v1->totweight * sizeof(MDeformWeight)); - } - else - v1->dw=NULL; -#endif - v1= addvertlist(efa->v2->co); + + v1= addvertlist(efa->v2->co, efa->v2); v1->f= efa->v2->f & ~128; efa->v2->tmp.v = v1; -#ifdef __NLA - v1->totweight = efa->v2->totweight; - if (efa->v2->totweight) { - v1->dw = MEM_mallocN (efa->v2->totweight * sizeof(MDeformWeight), "deformWeight"); - memcpy (v1->dw, efa->v2->dw, efa->v2->totweight * sizeof(MDeformWeight)); - } - else - v1->dw=NULL; -#endif - v1= addvertlist(efa->v3->co); + + v1= addvertlist(efa->v3->co, efa->v3); v1->f= efa->v3->f & ~128; efa->v3->tmp.v = v1; -#ifdef __NLA - v1->totweight = efa->v3->totweight; - if (efa->v3->totweight) { - v1->dw = MEM_mallocN (efa->v3->totweight * sizeof(MDeformWeight), "deformWeight"); - memcpy (v1->dw, efa->v3->dw, efa->v3->totweight * sizeof(MDeformWeight)); - } - else - v1->dw=NULL; -#endif + if (efa->v4) { - v1= addvertlist(efa->v4->co); + v1= addvertlist(efa->v4->co, efa->v4); v1->f= efa->v4->f & ~128; efa->v4->tmp.v = v1; -#ifdef __NLA - v1->totweight = efa->v4->totweight; - if (efa->v4->totweight) { - v1->dw = MEM_mallocN (efa->v4->totweight * sizeof(MDeformWeight), "deformWeight"); - memcpy (v1->dw, efa->v4->dw, efa->v4->totweight * sizeof(MDeformWeight)); - } - else - v1->dw=NULL; -#endif } /* Needs better adaption of creases? */ @@ -4595,7 +4469,7 @@ static void bevel_mesh(float bsize, int allfaces) cent[0]= (min[0]+max[0])/2; cent[1]= (min[1]+max[1])/2; cent[2]= (min[2]+max[2])/2; - eve2= addvertlist(cent); + eve2= addvertlist(cent, NULL); eve2->f |= 1; eed= em->edges.first; while (eed) { @@ -5494,7 +5368,7 @@ void mesh_rip(void) for(eve = em->verts.last; eve; eve= eve->prev) { eve->tmp.v = NULL; if(eve->f & SELECT) { - eve->tmp.v = addvertlist(eve->co); + eve->tmp.v = addvertlist(eve->co, eve); eve->f &= ~SELECT; eve->tmp.v->f |= SELECT; } diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 57802d3eb3e..280ca5be08b 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -95,6 +95,7 @@ #include "BKE_anim.h" #include "BKE_armature.h" #include "BKE_constraint.h" +#include "BKE_customdata.h" #include "BKE_blender.h" #include "BKE_booleanops.h" #include "BKE_curve.h" @@ -360,19 +361,24 @@ static int return_editmesh_indexar(int *tot, int **indexar, float *cent) static int return_editmesh_vgroup(char *name, float *cent) { EditMesh *em = G.editMesh; + MDeformVert *dvert; EditVert *eve; int i, totvert=0; cent[0]= cent[1]= cent[2]= 0.0; - if (G.obedit->actdef) { + if(G.obedit->actdef) { /* find the vertices */ for(eve= em->verts.first; eve; eve= eve->next) { - for (i=0; i<eve->totweight; i++){ - if(eve->dw[i].def_nr == (G.obedit->actdef-1)) { - totvert++; - VecAddf(cent, cent, eve->co); + dvert= CustomData_em_get(&em->vdata, eve->data, LAYERTYPE_MDEFORMVERT); + + if(dvert) { + for(i=0; i<dvert->totweight; i++){ + if(dvert->dw[i].def_nr == (G.obedit->actdef-1)) { + totvert++; + VecAddf(cent, cent, eve->co); + } } } } diff --git a/source/blender/src/retopo.c b/source/blender/src/retopo.c index 164823693a0..0c78d858f29 100644 --- a/source/blender/src/retopo.c +++ b/source/blender/src/retopo.c @@ -290,7 +290,7 @@ void retopo_paint_apply() for(i=0; i<hitcount; ++i) { RetopoPaintPoint *intersection= BLI_findlink(&rpd->intersections,i); retopo_do_2d(G.vd,&intersection->loc.x, hitco, 1); - intersection->eve= addvertlist(hitco); + intersection->eve= addvertlist(hitco, NULL); intersection->eve->f= SELECT; } diff --git a/source/blender/src/verse_mesh.c b/source/blender/src/verse_mesh.c index 851c2dcc77c..1445c5471d1 100644 --- a/source/blender/src/verse_mesh.c +++ b/source/blender/src/verse_mesh.c @@ -684,7 +684,7 @@ void post_vertex_create(VerseVert *vvert) * vertexes, because addvertlist() sends new vertex to verse * server if em->vnode isn't NULL */ em->vnode = NULL; - eve = addvertlist(vvert->co); + eve = addvertlist(vvert->co, NULL); em->vnode = (void*)geom_vnode; eve->vvert = (void*)vvert; @@ -1557,11 +1557,11 @@ void create_edit_mesh_from_geom_node(VNode *vnode) /* create all EditVerts */ while(vvert) { - eve = addvertlist(vvert->co); + eve = addvertlist(vvert->co, NULL); eve->f = 0; eve->h = 0; - eve->dw = NULL; + eve->data = NULL; eve->keyindex = keyindex; eve->vvert = (void*)vvert; |