[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