Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2006-11-12 02:23:15 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2006-11-12 02:23:15 +0300
commite4a1eb4e09384aee760d45db1841666c92972743 (patch)
treeb83af584c08afa2e08c21da528d4defde8813bf9 /source/blender/blenkernel
parent8857f4ce86cd277d45e513ef1025cd91c4c74753 (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/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_customdata.h7
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c12
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c36
-rw-r--r--source/blender/blenkernel/intern/customdata.c93
4 files changed, 98 insertions, 50 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;