[Bf-blender-cvs] [416d164] master: Projection Paint: move to looptri data
Campbell Barton
noreply at git.blender.org
Fri Jul 17 14:03:59 CEST 2015
Commit: 416d164fecae8aeaa035c3bc2d47f7c07c970e48
Author: Campbell Barton
Date: Fri Jul 17 20:23:33 2015 +1000
Branches: master
https://developer.blender.org/rB416d164fecae8aeaa035c3bc2d47f7c07c970e48
Projection Paint: move to looptri data
===================================================================
M source/blender/editors/sculpt_paint/paint_image_proj.c
===================================================================
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 1549c31..145bdbc 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -143,12 +143,10 @@ BLI_INLINE unsigned char f_to_char(const float val)
#define PROJ_FACE_SEAM1 (1 << 0) /* If this face has a seam on any of its edges */
#define PROJ_FACE_SEAM2 (1 << 1)
#define PROJ_FACE_SEAM3 (1 << 2)
-#define PROJ_FACE_SEAM4 (1 << 3)
#define PROJ_FACE_NOSEAM1 (1 << 4)
#define PROJ_FACE_NOSEAM2 (1 << 5)
#define PROJ_FACE_NOSEAM3 (1 << 6)
-#define PROJ_FACE_NOSEAM4 (1 << 7)
/* face winding */
#define PROJ_FACE_WINDING_INIT 1
@@ -340,25 +338,34 @@ typedef struct ProjPaintState {
#ifndef PROJ_DEBUG_NOSEAMBLEED
char *faceSeamFlags; /* store info about faces, if they are initialized etc*/
char *faceWindingFlags; /* save the winding of the face in uv space, helps as an extra validation step for seam detection */
- float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */
+ float (*faceSeamUVs)[3][2]; /* expanded UVs for faces to use as seams */
LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */
#endif
SpinLock *tile_lock;
DerivedMesh *dm;
- int dm_totface;
- int dm_totedge;
- int dm_totvert;
- int dm_release;
-
- MVert *dm_mvert;
- MEdge *dm_medge;
- MFace *dm_mface;
- MTFace *dm_mtface_stencil;
-
- MTFace **dm_mtface;
- MTFace **dm_mtface_clone; /* other UV map, use for cloning between layers */
+ int dm_totlooptri;
+ int dm_totpoly;
+ int dm_totedge;
+ int dm_totvert;
+ bool dm_release;
+
+ const MVert *dm_mvert;
+ const MEdge *dm_medge;
+ const MPoly *dm_mpoly;
+ const MLoop *dm_mloop;
+ const MLoopTri *dm_mlooptri;
+
+ const MLoopUV *dm_mloopuv_stencil;
+
+ /**
+ * \note These UV layers are aligned to \a dm_mlooptri
+ * but each pointer references the start of the layer,
+ * so a loop indirection is needed as well.
+ */
+ const MLoopUV **dm_mloopuv;
+ const MLoopUV **dm_mloopuv_clone; /* other UV map, use for cloning between layers */
} ProjPaintState;
typedef union pixelPointer {
@@ -414,39 +421,70 @@ typedef struct {
} TileInfo;
+
+/* -------------------------------------------------------------------- */
+
+/** \name MLoopTri accessor functions.
+ * \{ */
+
+BLI_INLINE const MPoly *ps_tri_index_to_mpoly(const ProjPaintState *ps, int tri_index)
+{
+ return &ps->dm_mpoly[ps->dm_mlooptri[tri_index].poly];
+}
+
+#define PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) \
+ ps->dm_mloop[lt->tri[0]].v, \
+ ps->dm_mloop[lt->tri[1]].v, \
+ ps->dm_mloop[lt->tri[2]].v,
+
+#define PS_LOOPTRI_AS_UV_3(uvlayer, lt) \
+ uvlayer[lt->poly][lt->tri[0]].uv, \
+ uvlayer[lt->poly][lt->tri[1]].uv, \
+ uvlayer[lt->poly][lt->tri[2]].uv,
+
+#define PS_LOOPTRI_ASSIGN_UV_3(uv_tri, uvlayer, lt) { \
+ (uv_tri)[0] = uvlayer[lt->poly][lt->tri[0]].uv; \
+ (uv_tri)[1] = uvlayer[lt->poly][lt->tri[1]].uv; \
+ (uv_tri)[2] = uvlayer[lt->poly][lt->tri[2]].uv; \
+} ((void)0)
+
+/** \} */
+
+
+
/* Finish projection painting structs */
-static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int face_index)
+static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int tri_index)
{
- MFace *mf = ps->dm_mface + face_index;
- Material *ma = ps->dm->mat[mf->mat_nr];
+ const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
+ Material *ma = ps->dm->mat[mp->mat_nr];
return ma ? ma->texpaintslot + ma->paint_active_slot : NULL;
}
-static Image *project_paint_face_paint_image(const ProjPaintState *ps, int face_index)
+static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_index)
{
if (ps->do_stencil_brush) {
return ps->stencil_ima;
}
else {
- MFace *mf = ps->dm_mface + face_index;
- Material *ma = ps->dm->mat[mf->mat_nr];
+ const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
+ Material *ma = ps->dm->mat[mp->mat_nr];
TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : NULL;
return slot ? slot->ima : ps->canvas_ima;
}
}
-static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int face_index)
+static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int tri_index)
{
- MFace *mf = ps->dm_mface + face_index;
- Material *ma = ps->dm->mat[mf->mat_nr];
+ const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
+ Material *ma = ps->dm->mat[mp->mat_nr];
return ma ? ma->texpaintslot + ma->paint_clone_slot : NULL;
}
-static Image *project_paint_face_clone_image(const ProjPaintState *ps, int face_index)
+static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_index)
{
- MFace *mf = ps->dm_mface + face_index;
- Material *ma = ps->dm->mat[mf->mat_nr];
+ const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
+ Material *ma = ps->dm->mat[mp->mat_nr];
TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_clone_slot : NULL;
return slot ? slot->ima : ps->clone_ima;
}
@@ -528,17 +566,13 @@ static float VecZDepthPersp(
/* Return the top-most face index that the screen space coord 'pt' touches (or -1) */
static int project_paint_PickFace(
const ProjPaintState *ps, const float pt[2],
- float w[3], int *r_side)
+ float w[3])
{
LinkNode *node;
float w_tmp[3];
- const float *v1, *v2, *v3, *v4;
int bucket_index;
- int face_index;
- int best_side = -1;
- int best_face_index = -1;
+ int best_tri_index = -1;
float z_depth_best = FLT_MAX, z_depth;
- MFace *mf;
bucket_index = project_bucket_offset_safe(ps, pt);
if (bucket_index == -1)
@@ -550,43 +584,32 @@ static int project_paint_PickFace(
* that the point its testing is only every originated from an existing face */
for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
- face_index = GET_INT_FROM_POINTER(node->link);
- mf = ps->dm_mface + face_index;
+ const int tri_index = GET_INT_FROM_POINTER(node->link);
+ const MLoopTri *lt = &ps->dm_mlooptri[tri_index];
+ const float *vtri_ss[3] = {
+ ps->screenCoords[ps->dm_mloop[lt->tri[0]].v],
+ ps->screenCoords[ps->dm_mloop[lt->tri[1]].v],
+ ps->screenCoords[ps->dm_mloop[lt->tri[2]].v],
+ };
- v1 = ps->screenCoords[mf->v1];
- v2 = ps->screenCoords[mf->v2];
- v3 = ps->screenCoords[mf->v3];
- if (isect_point_tri_v2(pt, v1, v2, v3)) {
- if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v2, v3, w_tmp);
- else z_depth = VecZDepthPersp(pt, v1, v2, v3, w_tmp);
+ if (isect_point_tri_v2(pt, UNPACK3(vtri_ss))) {
+ if (ps->is_ortho) {
+ z_depth = VecZDepthOrtho(pt, UNPACK3(vtri_ss), w_tmp);
+ }
+ else {
+ z_depth = VecZDepthPersp(pt, UNPACK3(vtri_ss), w_tmp);
+ }
if (z_depth < z_depth_best) {
- best_face_index = face_index;
- best_side = 0;
+ best_tri_index = tri_index;
z_depth_best = z_depth;
copy_v3_v3(w, w_tmp);
}
}
- else if (mf->v4) {
- v4 = ps->screenCoords[mf->v4];
-
- if (isect_point_tri_v2(pt, v1, v3, v4)) {
- if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v3, v4, w_tmp);
- else z_depth = VecZDepthPersp(pt, v1, v3, v4, w_tmp);
-
- if (z_depth < z_depth_best) {
- best_face_index = face_index;
- best_side = 1;
- z_depth_best = z_depth;
- copy_v3_v3(w, w_tmp);
- }
- }
- }
}
- *r_side = best_side;
- return best_face_index; /* will be -1 or a valid face */
+ return best_tri_index; /* will be -1 or a valid face */
}
/* Converts a uv coord into a pixel location wrapping if the uv is outside 0-1 range */
@@ -608,30 +631,25 @@ static bool project_paint_PickColor(
const ProjPaintState *ps, const float pt[2],
float *rgba_fp, unsigned char *rgba, const bool interp)
{
+ const MLoopTri *lt;
+ const float *lt_tri_uv[3];
float w[3], uv[2];
- int side;
- int face_index;
- MTFace *tf;
+ int tri_index;
Image *ima;
ImBuf *ibuf;
int xi, yi;
+ tri_index = project_paint_PickFace(ps, pt, w);
- face_index = project_paint_PickFace(ps, pt, w, &side);
-
- if (face_index == -1)
+ if (tri_index == -1)
return 0;
- tf = *(ps->dm_mtface + face_index);
+ lt = &ps->dm_mlooptri[tri_index];
+ PS_LOOPTRI_ASSIGN_UV_3(lt_tri_uv, ps->dm_mloopuv, lt);
- if (side == 0) {
- interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
- }
- else { /* QUAD */
- interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
- }
+ interp_v2_v2v2v2(uv, UNPACK3(lt_tri_uv), w);
- ima = project_paint_face_paint_image(ps, face_index);
+ ima = project_paint_face_paint_image(ps, tri_index);
ibuf = BKE_image_get_first_ibuf(ima); /* we must have got the imbuf before getting here */
if (!ibuf) return 0;
@@ -693,13 +711,14 @@ static bool project_paint_PickColor(
return 1;
}
-/* Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusuion test)
- * return...
- * 0 : no occlusion
- * -1 : no occlusion but 2D intersection is true (avoid testing the other half of a quad)
- * 1 : occluded
- * 2 : occluded with w[3] weights set (need to know in some cases) */
-
+/**
+ * Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusuion test)
+ * \return
+ * - `0`: no occlusion
+ * - `-1`: no occlusion but 2D intersection is true
+ * - `1`: occluded
+ * - `2`: occluded with `w[3]` weights set (need to know in some cases)
+ */
static int project_paint_occlude_ptv(
const float pt[3],
const float v1[4], const float v2[4], const float v3[4],
@@ -734,26 +753,30 @@ static int project_paint_occlude_ptv(
static int project_paint_occlude_ptv_clip(
- const ProjPaintState *ps, const MFace *mf,
- const float pt[3], const float v1[4], const float v2[4], const float v3[4],
- const int side)
+ const float pt[3],
+ const float v1[4], const float v2[4], const float v3[4],
+ const float v1_3d[3], const float v2_3d[3], const float v3_3d[3],
+ float w[3], const bool is_ortho, RegionView3D *rv3d)
{
- float w[3], wco[3];
- int ret = project_paint_oc
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list