[Bf-blender-cvs] [3566bb561c8] soc-2017-sculpting_improvements: Added method to remove vertices from basic meshes by remapping the v/e/l/p custom data arrays.

Sebastian Witt noreply at git.blender.org
Mon Aug 7 18:22:33 CEST 2017


Commit: 3566bb561c89933e3b72142ec52e3d7fad72a8f9
Author: Sebastian Witt
Date:   Mon Aug 7 18:19:50 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rB3566bb561c89933e3b72142ec52e3d7fad72a8f9

Added method to remove vertices from basic meshes by remapping the v/e/l/p custom data arrays.

===================================================================

M	source/blender/editors/sculpt_paint/sculpt.c

===================================================================

diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4a91043f24c..8f2d0242ea0 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -7202,39 +7202,142 @@ static int get_adjacent_edge(Mesh *me, MeshElemMap *emap, int curr_edge, int v_e
 	return -1;
 }
 
+/*TODO:Remove Temp debug function*/
+static char *cd_type_name(int t)
+{
+	char *name = "";
+	switch(t) {
+		case -1 : name = "CD_AUTO_FROM_NAME	 ";break;
+		case  0 : name = "CD_MVERT         	 ";break;
+		case  1 : name = "CD_MSTICKY       	 ";break;  /* DEPRECATED */
+		case  2 : name = "CD_MDEFORMVERT   	 ";break;
+		case  3 : name = "CD_MEDGE         	 ";break;
+		case  4 : name = "CD_MFACE         	 ";break;
+		case  5 : name = "CD_MTFACE        	 ";break;
+		case  6 : name = "CD_MCOL          	 ";break;
+		case  7 : name = "CD_ORIGINDEX     	 ";break;
+		case  8 : name = "CD_NORMAL          ";break;
+			/*	CD_POLYINDEX        = 9, */
+		case 10 : name = "CD_PROP_FLT        ";break;
+		case 11 : name = "CD_PROP_INT        ";break;
+		case 12 : name = "CD_PROP_STR        ";break;
+		case 13 : name = "CD_ORIGSPACE       ";break;  /* for modifier stack face location mapping */
+		case 14 : name = "CD_ORCO            ";break;
+		case 15 : name = "CD_MTEXPOLY        ";break;
+		case 16 : name = "CD_MLOOPUV         ";break;
+		case 17 : name = "CD_MLOOPCOL        ";break;
+		case 18 : name = "CD_TANGENT         ";break;
+		case 19 : name = "CD_MDISPS          ";break;
+		case 20 : name = "CD_PREVIEW_MCOL    ";break;  /* for displaying weightpaint colors */
+			/*	CD_ID_MCOL          = 21, */
+		case 22 : name = "CD_TEXTURE_MLOOPCOL";break;
+		case 23 : name = "CD_CLOTH_ORCO      ";break;
+		case 24 : name = "CD_RECAST          ";break;
+
+			/* BMESH ONLY START */
+		case 25 : name = "CD_MPOLY           ";break;
+		case 26 : name = "CD_MLOOP           ";break;
+		case 27 : name = "CD_SHAPE_KEYINDEX  ";break;
+		case 28 : name = "CD_SHAPEKEY        ";break;
+		case 29 : name = "CD_BWEIGHT         ";break;
+		case 30 : name = "CD_CREASE          ";break;
+		case 31 : name = "CD_ORIGSPACE_MLOOP ";break;
+		case 32 : name = "CD_PREVIEW_MLOOPCOL";break;
+		case 33 : name = "CD_BM_ELEM_PYPTR   ";break;
+			/* BMESH ONLY END */
+		case 34 : name = "CD_PAINT_MASK      ";break;
+		case 35 : name = "CD_GRID_PAINT_MASK ";break;
+		case 36 : name = "CD_MVERT_SKIN      ";break;
+		case 37 : name = "CD_FREESTYLE_EDGE  ";break;
+		case 38 : name = "CD_FREESTYLE_FACE  ";break;
+		case 39 : name = "CD_MLOOPTANGENT    ";break;
+		case 40 : name = "CD_TESSLOOPNORMAL  ";break;
+		case 41 : name = "CD_CUSTOMLOOPNORMAL";break;
+
+		case 42 : name = "CD_NUMTYPES        ";break;
+		default: name = "No Name";
+	}
+	return name;
+}
+
 #if 0
-/*static void add_from_map(const int v, MeshElemMap *map, int *data, int *num, int *max)
+static void debug_cd(Mesh *me)
 {
-	int count = map[v].count;
-	if (count > 0) {
-		if (num + count > max) {
-			*max += fmax(STORE_ESTIMATE_RESIZE, count);
-			data = MEM_reallocN(data, sizeof(int) * (*max));
-		}
-		for (int i = 0; i < count; i++) {
-			data[(*num)] = map[v].indices[i];
-			*num = *num + 1;
+	char *name = "";
+	printf("Debugging Custom Data:\n\n");
+	printf("%i Customdata Layers in vdata\n", CustomData_number_of_layers_typemask(&me->vdata, CD_MASK_EVERYTHING));
+	printf("%i Customdata Layers in edata\n", CustomData_number_of_layers_typemask(&me->edata, CD_MASK_EVERYTHING));
+	printf("%i Customdata Layers in ldata\n", CustomData_number_of_layers_typemask(&me->ldata, CD_MASK_EVERYTHING));
+	printf("%i Customdata Layers in pdata\n", CustomData_number_of_layers_typemask(&me->pdata, CD_MASK_EVERYTHING));
+	for (int i = 0; i < CustomData_number_of_layers_typemask(&me->vdata, CD_MASK_EVERYTHING); i++) {
+		name = cd_type_name(me->vdata.layers[i].type);
+		printf("Layer found with name %s\n", name);
+	}
+	for (int i = 0; i < CustomData_number_of_layers_typemask(&me->edata, CD_MASK_EVERYTHING); i++) {
+		name = cd_type_name(me->edata.layers[i].type);
+		printf("Layer found with name %s\n", name);
+	}
+	for (int i = 0; i < CustomData_number_of_layers_typemask(&me->ldata, CD_MASK_EVERYTHING); i++) {
+		name = cd_type_name(me->ldata.layers[i].type);
+		printf("Layer found with name %s\n", name);
+	}
+	for (int i = 0; i < CustomData_number_of_layers_typemask(&me->pdata, CD_MASK_EVERYTHING); i++) {
+		name = cd_type_name(me->pdata.layers[i].type);
+		printf("Layer found with name %s\n", name);
+	}
+}
+#endif
+
+/* Copy customdata from source to destination. Layers need to be matching!
+ * redirect_map needs to be the new positions ofelements in the dest array. -1 marks elements which do not get copied over. */
+static void CustomData_copy_partial(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int *redirect_map, int tot_elem)
+{
+	int num_layers_to_copy;
+	int d_size;
+	CustomDataLayer *curr_l, *dest_l;
+	char *name;
+
+	num_layers_to_copy = CustomData_number_of_layers_typemask(source, mask);
+
+	for (int l = 0; l < num_layers_to_copy; l++) {
+		curr_l = &source->layers[l];
+		dest_l = &dest->layers[l];
+		if (CD_TYPE_AS_MASK(curr_l->type) & mask) {
+			for (int i = 0; i < tot_elem; i++) {
+				if(redirect_map[i] != -1) {
+					d_size = CustomData_sizeof(curr_l->type);
+					memcpy(dest_l->data + redirect_map[i] * d_size, curr_l->data + i * d_size, d_size);
+				}
+			}
+			name = cd_type_name(curr_l->type);
+			printf("Layer %s copied %i values of size %i.\n", name, tot_elem, CustomData_sizeof(curr_l->type));
 		}
 	}
 }
 
-static int *allocate_estimate(int r_num, const int count, float factor)
-{
-	r_num = (int)(count * (factor + STORE_ESTIMATE_BIAS));
-	return MEM_callocN(sizeof(int) * r_num, __func__);
-}*/
+/* Function used to remove vertices from a basic mesh
+ * Can be optimised easily be introucing multithreading
+ * Parts and ideas how multithreading can be introduced are marked with "MT:"
+ * TODO: Add Multithreading */
+static void remove_verts_from_mesh(Mesh *me, int *v_to_rm, int num_v_to_rm){
+	int *v_rd_table, *e_rd_table, *l_rd_table, *p_rd_table;
+	int next_del = 0, next_del_pos = 0;
+	MEdge e;
+	MLoop l;
+	MPoly p;
 
-/* Doesn't work external pointers to the vert/edge/loop/poly structure break 
- * Is there another way than converting to bmesh?
- */
+	int n_totvert, n_totedge, n_totloop, n_totpoly;
 
-static void remove_verts_from_mesh(Mesh *me, int *v_to_rm, int num_v_to_rm, MeshElemMap *emap, MeshElemMap *lmap, MeshElemMap *pmap){
-	int *v_rd_table, *e_rd_table, *l_rd_table, *p_rd_table;
-	int sum = 0, next_del = 0, next_del_pos = 0;
+	CustomData vdata, edata, ldata, pdata;
 
+	/* MT: Prefix Sum / Scan to calculate new positions for vertices.
+	 * Calculating the new positions with the vertices removed
+	 */
 	v_rd_table = MEM_callocN(sizeof(int) * me->totvert, "Vertex redirect table");
 
-	/* Prefix Sum / Scan to calculate new positions for vertices. Multithreading?*/
+	qsort(v_to_rm, num_v_to_rm, sizeof(int), cmpfunc);
+
+	n_totvert = 0;
 	next_del = v_to_rm[0];
 	for (int i = 0; i < me->totvert; i++) {
 		if (i == next_del) {
@@ -7244,39 +7347,94 @@ static void remove_verts_from_mesh(Mesh *me, int *v_to_rm, int num_v_to_rm, Mesh
 			}
 			v_rd_table[i] = -1;
 		} else {
-			v_rd_table[i] = sum;
-			sum ++;
+			v_rd_table[i] = n_totvert;
+			n_totvert ++;
 		}
 	}
 
-	/*int *e_to_rm = NULL, *l_to_rm = NULL, *p_to_rm = NULL;
-	int num_e_to_rm = 0, num_l_to_rm = 0, num_p_to_rm = 0;
-	int max_e_to_rm = 0, max_l_to_rm = 0, max_p_to_rm = 0;*/
+	/* MT: parallelize loop, !shared access to sum value
+	 * Calculate new edge positions + remap vertice pointer
+	 */
+	e_rd_table = MEM_callocN(sizeof(int) * me->totedge, "Edge redirect table");
+	n_totedge = 0;
+	for (int i = 0; i < me->totedge; i++) {
+		e = me->medge[i];
+		if(v_rd_table[e.v1] == -1 || v_rd_table[e.v2] == -1) {
+			e_rd_table[i] = -1;
+		} else {
+			e.v1 = v_rd_table[e.v1];
+			e.v2 = v_rd_table[e.v2];
+			me->medge[i] = e;
+			e_rd_table[i] = n_totedge;
+			n_totedge ++;
+		}
+	}
+
+	/* MT: same as above
+	 * Calculate new loop positions + remap edge pointers */
+	l_rd_table = MEM_callocN(sizeof(int) * me->totloop, "Loop redirect table");
+	n_totloop = 0;
+	for (int i = 0; i < me->totloop; i++) {
+		l = me->mloop[i];
+		if(v_rd_table[l.v] == -1 || e_rd_table[l.e] == -1) {
+			l_rd_table[i] = -1;
+		} else {
+			l.v = v_rd_table[l.v];
+			l.e = e_rd_table[l.e];
+			me->mloop[i] = l;
+			l_rd_table[i] = n_totloop;
+			n_totloop ++;
+		}
+	}
+
+	/* MT: same as above
+	 * Calculate new poly positions + remap pointers */
+	p_rd_table = MEM_callocN(sizeof(int) * me->totpoly, "Poly redirect table");
+	n_totpoly = 0;
+	for (int i = 0; i < me->totpoly; i++) {
+		p = me->mpoly[i];
+		for(int l = p.loopstart; l < p.loopstart + p.totloop; l++){
+			if(l_rd_table[l] == -1) {
+				p_rd_table[i] = -1;
+				/* TODO: Bad practise? easily solved other way*/
+				goto skip_poly;
+			}
+		}
+		me->mpoly[i].loopstart = l_rd_table[me->mpoly[i].loopstart];
+		p_rd_table[i] = n_totpoly;
+		n_totpoly ++;
+		skip_poly:;
+	}
 
+	/*Redirection tables are done. Continue to copy and allocate new Customdata blocks*/
+	CustomData_copy(&me->vdata, &vdata, CD_MASK_EVERYTHING, CD_CALLOC, n_totvert);
+	CustomData_copy(&me->edata, &edata, CD_MASK_EVERYTHING, CD_CALLOC, n_totedge);
+	CustomData_copy(&me->ldata, &ldata, CD_MASK_EVERYTHING, CD_CALLOC, n_totloop);
+	CustomData_copy(&me->pdata, &pdata, CD_MASK_EVERYTHING, CD_CALLOC, n_totpoly);
 
-	/*e_to_rm = allocate_estimate(max_e_to_rm, num_v_to_rm, 4.0f);
-	l_to_rm = allocate_estimate(max_l_to_rm, num_v_to_rm, 4.0f);
-	p_to_rm = allocate_estimate(max_p_to_rm, num_v_to_rm, 1.0f);
+	CustomData_copy_partial(&me->vdata, &vdata, CD_MASK_EVERYTHING, v_rd_table, me->totvert);
+	CustomData_copy_partial(&me->edata, &edata, CD_MASK_EVERYTHING, e_rd_table, me->totedge);
+	CustomData_copy_partial(&me->ldata, &ldata, CD_MASK_EVERYTHING, l_rd_table, me->totloop);
+	CustomData_copy_partial(&me->pdata, &pdata, CD_MASK_EVERYTHING, p_rd_table, me->totpoly);
 
-	for (int i = 0; i < num_v_to_rm; i++) {
-		add_from_map(v_to_rm[i], emap, e_to_rm, &num_e_to_rm, &max_e_to_rm);


@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list