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:
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h4
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c53
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c88
3 files changed, 100 insertions, 45 deletions
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index 3c5377d7bf6..ee9e63e6975 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -117,6 +117,10 @@ void BKE_mesh_edge_poly_map_create(
const struct MEdge *medge, const int totedge,
const struct MPoly *mpoly, const int totpoly,
const struct MLoop *mloop, const int totloop);
+void BKE_mesh_origindex_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const int totorig,
+ const int *final_origindex, const int totfinal);
/* smoothgroups */
int *BKE_mesh_calc_smoothgroups(
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index cbf4b4906f5..94f29b5b1a4 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -36,6 +36,7 @@
#include "BLI_math.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_customdata.h"
#include "BLI_strict_flags.h"
@@ -289,6 +290,58 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map, int **r_mem,
*r_mem = indices;
}
+/**
+ * This function creates a map so the source-data (vert/edge/loop/poly)
+ * can loop over the destination data (using the destination arrays origindex).
+ *
+ * This has the advantage that it can operate on any data-types.
+ *
+ * \param totsource The total number of elements the that \a final_origindex points to.
+ * \param totfinal The size of \a final_origindex
+ * \param final_origindex The size of the final array.
+ *
+ * \note ``totsource`` could be ``totpoly``,
+ * ``totfinal`` could be ``tottessface`` and ``final_origindex`` its ORIGINDEX customdata.
+ * This would allow an MPoly to loop over its tessfaces.
+ */
+void BKE_mesh_origindex_map_create(MeshElemMap **r_map, int **r_mem,
+ const int totsource,
+ const int *final_origindex, const int totfinal)
+{
+ MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totsource, "poly-tessface map");
+ int *indices = MEM_mallocN(sizeof(int) * (size_t)totfinal, "poly-tessface map mem");
+ int *index_step;
+ int i;
+
+ /* count face users */
+ for (i = 0; i < totfinal; i++) {
+ if (final_origindex[i] != ORIGINDEX_NONE) {
+ BLI_assert(final_origindex[i] < totsource);
+ map[final_origindex[i]].count++;
+ }
+ }
+
+ /* create offsets */
+ index_step = indices;
+ for (i = 0; i < totsource; i++) {
+ map[i].indices = index_step;
+ index_step += map[i].count;
+
+ /* re-count, using this as an index below */
+ map[i].count = 0;
+ }
+
+ /* assign poly-tessface users */
+ for (i = 0; i < totfinal; i++) {
+ if (final_origindex[i] != ORIGINDEX_NONE) {
+ MeshElemMap *map_ele = &map[final_origindex[i]];
+ map_ele->indices[map_ele->count++] = i;
+ }
+ }
+
+ *r_map = map;
+ *r_mem = indices;
+}
/** \} */
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 9d7bad2591e..31a344da4a1 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -56,6 +56,7 @@
#include "BKE_depsgraph.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
@@ -2756,11 +2757,11 @@ typedef struct VPaintData {
/* modify 'me->mcol' directly, since the derived mesh is drawing from this
* array, otherwise we need to refresh the modifier stack */
- int use_fast_update;
+ bool use_fast_update;
/* mpoly -> mface mapping */
- MemArena *polyfacemap_arena;
- ListBase *polyfacemap;
+ MeshElemMap *polyfacemap;
+ void *polyfacemap_mem;
/* loops tagged as having been painted, to apply shared vertex color
* blending only to modified loops */
@@ -2772,31 +2773,19 @@ typedef struct VPaintData {
static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
{
- MFace *mf;
- PolyFaceMap *e;
- int *origIndex;
- int i;
-
- vd->polyfacemap_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vpaint tmp");
- BLI_memarena_use_calloc(vd->polyfacemap_arena);
+ const int *tessface_origindex;
- vd->polyfacemap = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(ListBase) * me->totpoly);
+ vd->polyfacemap = NULL;
+ vd->polyfacemap_mem = NULL;
- origIndex = CustomData_get_layer(&me->fdata, CD_ORIGINDEX);
- mf = me->mface;
+ tessface_origindex = CustomData_get_layer(&me->fdata, CD_ORIGINDEX);
- if (!origIndex)
+ if (!tessface_origindex)
return;
- for (i = 0; i < me->totface; i++, mf++, origIndex++) {
- if (*origIndex == ORIGINDEX_NONE)
- continue;
-
- e = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(PolyFaceMap));
- e->facenr = i;
-
- BLI_addtail(&vd->polyfacemap[*origIndex], e);
- }
+ BKE_mesh_origindex_map_create(&vd->polyfacemap, (int **)&vd->polyfacemap_mem,
+ me->totpoly,
+ tessface_origindex, me->totface);
}
static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const float UNUSED(mouse[2]))
@@ -2868,6 +2857,15 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
return 1;
}
+BLI_INLINE int mesh_tessface_vertex_index(MFace *tessface, unsigned int v)
+{
+ if (tessface->v1 == v) return 0;
+ if (tessface->v2 == v) return 1;
+ if (tessface->v3 == v) return 2;
+ if (v && (tessface->v4 == v)) return 3;
+ return -1;
+}
+
static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
const unsigned int index, const float mval[2],
const float brush_size_pressure, const float brush_alpha_pressure)
@@ -2879,7 +2877,6 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
MCol *mc;
MLoop *ml;
MLoopCol *mlc;
- PolyFaceMap *e;
unsigned int *lcol = ((unsigned int *)me->mloopcol) + mpoly->loopstart;
unsigned int *lcolorig = ((unsigned int *)vp->vpaint_prev) + mpoly->loopstart;
bool *mlooptag = (vpd->mlooptag) ? vpd->mlooptag + mpoly->loopstart : NULL;
@@ -2942,31 +2939,28 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
}
if (vpd->use_fast_update) {
+ const MeshElemMap *map = &vpd->polyfacemap[index];
+
/* update vertex colors for tessellations incrementally,
* rather then regenerating the tessellation altogether */
- for (e = vpd->polyfacemap[index].first; e; e = e->next) {
- mf = &me->mface[e->facenr];
- mc = &me->mcol[e->facenr * 4];
- mftag = &vpd->mfacetag[e->facenr * 4];
+ for (i = 0; i < map->count; i++) {
+ const int index_tessface = map->indices[i];
+
+ mf = &me->mface[index_tessface];
+ mc = &me->mcol[index_tessface * 4];
+ mftag = &vpd->mfacetag[index_tessface * 4];
ml = me->mloop + mpoly->loopstart;
mlc = me->mloopcol + mpoly->loopstart;
+
for (j = 0; j < totloop; j++, ml++, mlc++) {
- if (ml->v == mf->v1) {
- MESH_MLOOPCOL_TO_MCOL(mlc, mc + 0);
- if (mlooptag) mftag[0] = mlooptag[j];
- }
- else if (ml->v == mf->v2) {
- MESH_MLOOPCOL_TO_MCOL(mlc, mc + 1);
- if (mlooptag) mftag[1] = mlooptag[j];
- }
- else if (ml->v == mf->v3) {
- MESH_MLOOPCOL_TO_MCOL(mlc, mc + 2);
- if (mlooptag) mftag[2] = mlooptag[j];
- }
- else if (mf->v4 && ml->v == mf->v4) {
- MESH_MLOOPCOL_TO_MCOL(mlc, mc + 3);
- if (mlooptag) mftag[3] = mlooptag[j];
+ /* search for the loop vertex within the tessface */
+ const int fidx = mesh_tessface_vertex_index(mf, ml->v);
+ if (fidx != -1) {
+ MESH_MLOOPCOL_TO_MCOL(mlc, mc + fidx);
+ if (mlooptag) {
+ mftag[fidx] = mlooptag[j];
+ }
}
}
}
@@ -3078,8 +3072,12 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
/* frees prev buffer */
copy_vpaint_prev(ts->vpaint, NULL, 0);
- if (vpd->polyfacemap_arena) {
- BLI_memarena_free(vpd->polyfacemap_arena);
+ if (vpd->polyfacemap) {
+ MEM_freeN(vpd->polyfacemap);
+ }
+
+ if (vpd->polyfacemap_mem) {
+ MEM_freeN(vpd->polyfacemap_mem);
}
if (vpd->mlooptag)