[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53657] trunk/blender/source/blender: fix [#33792] Accessing a bmesh object created by from_object crashes blender

Campbell Barton ideasman42 at gmail.com
Tue Jan 8 15:25:19 CET 2013


Revision: 53657
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53657
Author:   campbellbarton
Date:     2013-01-08 14:25:17 +0000 (Tue, 08 Jan 2013)
Log Message:
-----------
fix [#33792] Accessing a bmesh object created by from_object crashes blender

Issue was customdata wasnt being initialized for layers in the destination BMesh but not in the source data.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_customdata.h
    trunk/blender/source/blender/blenkernel/intern/customdata.c
    trunk/blender/source/blender/blenkernel/intern/modifiers_bmesh.c
    trunk/blender/source/blender/bmesh/intern/bmesh_mesh_conv.c

Modified: trunk/blender/source/blender/blenkernel/BKE_customdata.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_customdata.h	2013-01-08 14:04:01 UTC (rev 53656)
+++ trunk/blender/source/blender/blenkernel/BKE_customdata.h	2013-01-08 14:25:17 UTC (rev 53657)
@@ -39,6 +39,7 @@
 #endif
 
 #include "../blenloader/BLO_sys_types.h" /* XXX, should have a more generic include for this */
+#include "BLI_utildefines.h"
 
 struct BMesh;
 struct ID;
@@ -304,7 +305,7 @@
 /* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
  * blocks of data. the CustomData's must not be compatible */
 void CustomData_to_bmesh_block(const struct CustomData *source, 
-                               struct CustomData *dest, int src_index, void **dest_block);
+                               struct CustomData *dest, int src_index, void **dest_block, bool use_default_init);
 void CustomData_from_bmesh_block(const struct CustomData *source, 
                                  struct CustomData *dest, void *src_block, int dest_index);
 

Modified: trunk/blender/source/blender/blenkernel/intern/customdata.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/customdata.c	2013-01-08 14:04:01 UTC (rev 53656)
+++ trunk/blender/source/blender/blenkernel/intern/customdata.c	2013-01-08 14:25:17 UTC (rev 53657)
@@ -2660,27 +2660,40 @@
 	if (count > SOURCE_BUF_SIZE) MEM_freeN(sources);
 }
 
+static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
+{
+	const LayerTypeInfo *typeInfo;
+	int offset = data->layers[n].offset;
+
+	typeInfo = layerType_getInfo(data->layers[n].type);
+
+	if (typeInfo->set_default) {
+		typeInfo->set_default((char *)*block + offset, 1);
+	}
+	else {
+		memset((char *)*block + offset, 0, typeInfo->size);
+	}
+}
+
 void CustomData_bmesh_set_default(CustomData *data, void **block)
 {
-	const LayerTypeInfo *typeInfo;
 	int i;
 
 	if (*block == NULL)
 		CustomData_bmesh_alloc_block(data, block);
 
 	for (i = 0; i < data->totlayer; ++i) {
-		int offset = data->layers[i].offset;
-
-		typeInfo = layerType_getInfo(data->layers[i].type);
-
-		if (typeInfo->set_default)
-			typeInfo->set_default((char *)*block + offset, 1);
-		else memset((char *)*block + offset, 0, typeInfo->size);
+		CustomData_bmesh_set_default_n(data, block, i);
 	}
 }
 
+/**
+ * \param use_default_init initializes data which can't be copied,
+ * typically you'll want to use this if the BM_xxx create function
+ * is called with BM_CREATE_SKIP_CD flag
+ */
 void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
-                               int src_index, void **dest_block)
+                               int src_index, void **dest_block, bool use_default_init)
 {
 	const LayerTypeInfo *typeInfo;
 	int dest_i, src_i, src_offset;
@@ -2696,11 +2709,14 @@
 		 * (this should work because layers are ordered by type)
 		 */
 		while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
+			if (use_default_init) {
+				CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
+			}
 			dest_i++;
 		}
 
 		/* if there are no more dest layers, we're done */
-		if (dest_i >= dest->totlayer) return;
+		if (dest_i >= dest->totlayer) break;
 
 		/* if we found a matching layer, copy the data */
 		if (dest->layers[dest_i].type == source->layers[src_i].type) {
@@ -2723,6 +2739,13 @@
 			dest_i++;
 		}
 	}
+
+	if (use_default_init) {
+		while (dest_i < dest->totlayer) {
+			CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
+			dest_i++;
+		}
+	}
 }
 
 void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,

Modified: trunk/blender/source/blender/blenkernel/intern/modifiers_bmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifiers_bmesh.c	2013-01-08 14:04:01 UTC (rev 53656)
+++ trunk/blender/source/blender/blenkernel/intern/modifiers_bmesh.c	2013-01-08 14:25:17 UTC (rev 53657)
@@ -96,7 +96,7 @@
 		v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
 		BM_elem_index_set(v, i); /* set_inline */
 
-		CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data);
+		CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data, true);
 		vtable[i] = v;
 
 		/* add bevel weight */
@@ -118,7 +118,7 @@
 		e->head.hflag = BM_edge_flag_from_mflag(me->flag);
 		BM_elem_index_set(e, i); /* set_inline */
 
-		CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data);
+		CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true);
 		etable[i] = e;
 
 		/* add crease */
@@ -168,10 +168,10 @@
 		l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
 
 		for (k = mp->loopstart; l; l = BM_iter_step(&liter), k++) {
-			CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data);
+			CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data, true);
 		}
 
-		CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data);
+		CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true);
 
 		if (face_normals) {
 			copy_v3_v3(f->no, face_normals[i]);

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_mesh_conv.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_mesh_conv.c	2013-01-08 14:04:01 UTC (rev 53656)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_mesh_conv.c	2013-01-08 14:25:17 UTC (rev 53657)
@@ -221,7 +221,7 @@
 		normal_short_to_float_v3(v->no, mvert->no);
 
 		/* Copy Custom Data */
-		CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
+		CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
 
 		BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
 
@@ -267,7 +267,7 @@
 		}
 
 		/* Copy Custom Data */
-		CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data);
+		CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
 
 		BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f);
 		BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f);
@@ -338,11 +338,11 @@
 		j = 0;
 		BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) {
 			/* Save index of correspsonding MLoop */
-			CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data);
+			CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data, true);
 		}
 
 		/* Copy Custom Data */
-		CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data);
+		CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
 	}
 
 	bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */




More information about the Bf-blender-cvs mailing list