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:
authorCampbell Barton <ideasman42@gmail.com>2015-07-27 08:52:54 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-07-27 09:01:56 +0300
commite48c4d73d378b5ac7e8679b1eea04b265ef31612 (patch)
tree74d831dfc943024f8d305785623600c0a5313987 /source/blender/blenkernel/intern
parentcdf2dbeb1fa28a91c5fea6b5b4de95f644dc970f (diff)
Replace MFace with looptri for dynamicpaint
D1429 by @lichtwerk, with edits
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c632
1 files changed, 293 insertions, 339 deletions
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 4372f9635c7..6f510d846f6 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -200,12 +200,11 @@ typedef struct PaintBakeData {
/* UV Image sequence format point */
typedef struct PaintUVPoint {
/* Pixel / mesh data */
- unsigned int face_index, pixel_index; /* face index on domain derived mesh */
+ unsigned int tri_index, pixel_index; /* tri index on domain derived mesh */
unsigned int v1, v2, v3; /* vertex indexes */
unsigned int neighbour_pixel; /* If this pixel isn't uv mapped to any face,
* but it's neighboring pixel is */
- short quad;
} PaintUVPoint;
typedef struct ImgSeqFormatData {
@@ -457,7 +456,7 @@ static void blendColors(const float t_color[3], float t_alpha, const float s_col
}
/* Mix two alpha weighed colors by a defined ratio. output is saved at a_color */
-static float mixColors(float a_color[3], float a_weight, float b_color[3], float b_weight, float ratio)
+static float mixColors(float a_color[3], float a_weight, const float b_color[3], float b_weight, float ratio)
{
float weight_ratio, factor;
if (b_weight) {
@@ -1465,24 +1464,26 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
/* apply color to every surface point */
#pragma omp parallel for schedule(static)
for (i = 0; i < sData->total_points; i++) {
- copy_v3_v3(pPoint[i].color, surface->init_color);
- pPoint[i].alpha = surface->init_color[3];
+ copy_v4_v4(pPoint[i].color, surface->init_color);
}
}
/* UV mapped texture */
else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) {
Tex *tex = surface->init_texture;
- MTFace *tface;
- MFace *mface = dm->getTessFaceArray(dm);
- int numOfFaces = dm->getNumTessFaces(dm);
+
+ const MLoop *mloop = dm->getLoopArray(dm);
+ const MLoopTri *mlooptri = dm->getLoopTriArray(dm);
+ const int tottri = dm->getNumLoopTri(dm);
+ const MLoopUV *mloopuv = NULL;
+
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
if (!tex) return;
/* get uv map */
- CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, surface->init_layername, uvname);
- tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
- if (!tface) return;
+ CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, surface->init_layername, uvname);
+ mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname);
+ if (!mloopuv) return;
/* for vertex surface loop through tfaces and find uv color
* that provides highest alpha */
@@ -1490,23 +1491,22 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
struct ImagePool *pool = BKE_image_pool_new();
#pragma omp parallel for schedule(static) shared(pool)
- for (i = 0; i < numOfFaces; i++) {
- int numOfVert = (mface[i].v4) ? 4 : 3;
+ for (i = 0; i < tottri; i++) {
float uv[3] = {0.0f};
int j;
- for (j = 0; j < numOfVert; j++) {
+ for (j = 0; j < 3; j++) {
TexResult texres = {0};
- unsigned int *vert = (&mface[i].v1) + j;
+ unsigned int vert = mloop[mlooptri[i].tri[j]].v;
/* remap to -1.0 to 1.0 */
- uv[0] = tface[i].uv[j][0] * 2.0f - 1.0f;
- uv[1] = tface[i].uv[j][1] * 2.0f - 1.0f;
+ uv[0] = mloopuv[mlooptri[i].tri[j]].uv[0] * 2.0f - 1.0f;
+ uv[1] = mloopuv[mlooptri[i].tri[j]].uv[1] * 2.0f - 1.0f;
multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false);
- if (texres.tin > pPoint[*vert].alpha) {
- copy_v3_v3(pPoint[*vert].color, &texres.tr);
- pPoint[*vert].alpha = texres.tin;
+ if (texres.tin > pPoint[vert].color[3]) {
+ copy_v3_v3(pPoint[vert].color, &texres.tr);
+ pPoint[vert].color[3] = texres.tin;
}
}
}
@@ -1525,8 +1525,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
/* collect all uvs */
for (j = 0; j < 3; j++) {
- int v = (f_data->uv_p[i].quad && j > 0) ? j + 1 : j;
- copy_v2_v2(&uv[j * 3], tface[f_data->uv_p[i].face_index].uv[v]);
+ copy_v2_v2(&uv[j * 3], mloopuv[mlooptri[f_data->uv_p[i].tri_index].tri[j]].uv);
}
/* interpolate final uv pos */
@@ -1540,7 +1539,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
/* apply color */
copy_v3_v3(pPoint[i].color, &texres.tr);
- pPoint[i].alpha = texres.tin;
+ pPoint[i].color[3] = texres.tin;
}
}
}
@@ -1549,46 +1548,40 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
/* for vertex surface, just copy colors from mcol */
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
- MLoop *mloop = dm->getLoopArray(dm);
- int numOfLoops = dm->getNumLoops(dm);
- MCol *col = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, surface->init_layername);
+ const MLoop *mloop = dm->getLoopArray(dm);
+ const int totloop = dm->getNumLoops(dm);
+ const MLoopCol *col = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, surface->init_layername);
if (!col) return;
#pragma omp parallel for schedule(static)
- for (i = 0; i < numOfLoops; i++) {
- pPoint[mloop[i].v].color[0] = 1.0f / 255.f * (float)col[i].b;
- pPoint[mloop[i].v].color[1] = 1.0f / 255.f * (float)col[i].g;
- pPoint[mloop[i].v].color[2] = 1.0f / 255.f * (float)col[i].r;
- pPoint[mloop[i].v].alpha = 1.0f / 255.f * (float)col[i].a;
+ for (i = 0; i < totloop; i++) {
+ rgba_uchar_to_float(pPoint[mloop[i].v].color, (const unsigned char *)&col[mloop[i].v].r);
}
}
else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
+ const MLoopTri *mlooptri = dm->getLoopTriArray(dm);
ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data;
int samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
- MCol *col = CustomData_get_layer_named(&dm->faceData, CD_MCOL, surface->init_layername);
+ // should this be replaced by CD_MLOOPCOL?
+ MLoopCol *col = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, surface->init_layername);
if (!col) return;
#pragma omp parallel for schedule(static)
for (i = 0; i < sData->total_points; i++) {
- int face_ind = f_data->uv_p[i].face_index;
- float colors[3][4] = {{0.0f, 0.0f, 0.0f, 0.0f}};
+ int tri_ind = f_data->uv_p[i].tri_index;
+ float colors[3][4];
float final_color[4];
int j;
+
/* collect color values */
for (j = 0; j < 3; j++) {
- int v = (f_data->uv_p[i].quad && j > 0) ? j + 1 : j;
- colors[j][0] = 1.0f / 255.f * (float)col[face_ind * 4 + v].b;
- colors[j][1] = 1.0f / 255.f * (float)col[face_ind * 4 + v].g;
- colors[j][2] = 1.0f / 255.f * (float)col[face_ind * 4 + v].r;
- colors[j][3] = 1.0f / 255.f * (float)col[face_ind * 4 + v].a;
+ rgba_uchar_to_float(colors[j], (const unsigned char *)&col[mlooptri[tri_ind].tri[j]].r);
}
-
+
/* interpolate final color */
- interp_v4_v4v4v4(final_color, colors[0], colors[1], colors[2],
- f_data->barycentricWeights[i * samples].v);
+ interp_v4_v4v4v4(final_color, UNPACK3(colors), f_data->barycentricWeights[i * samples].v);
- copy_v3_v3(pPoint[i].color, final_color);
- pPoint[i].alpha = final_color[3];
+ copy_v4_v4(pPoint[i].color, final_color);
}
}
}
@@ -1724,7 +1717,7 @@ static DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd,
#pragma omp parallel for schedule(static)
for (i = 0; i < sData->total_points; i++) {
/* blend dry and wet layer */
- blendColors(pPoint[i].color, pPoint[i].alpha, pPoint[i].e_color, pPoint[i].e_alpha, &fcolor[i * 4]);
+ blendColors(pPoint[i].color, pPoint[i].color[3], pPoint[i].e_color, pPoint[i].e_color[3], &fcolor[i * 4]);
}
/* viewport preview */
@@ -2051,7 +2044,7 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
* Check if shifted point is on same face -> it's a correct neighbor
* (and if it isn't marked as an "edge pixel")
*/
- if ((tPoint->face_index == cPoint->face_index) && (tPoint->neighbour_pixel == -1))
+ if ((tPoint->tri_index == cPoint->tri_index) && (tPoint->neighbour_pixel == -1))
return (x + w * y);
/*
@@ -2062,7 +2055,7 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
* This should work fine as long as uv island
* margin is > 1 pixel.
*/
- if ((tPoint->face_index != -1) && (tPoint->neighbour_pixel == -1)) {
+ if ((tPoint->tri_index != -1) && (tPoint->neighbour_pixel == -1)) {
return (x + w * y);
}
@@ -2080,9 +2073,10 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
* TODO: Implement something more accurate / optimized?
*/
{
- int numOfFaces = dm->getNumTessFaces(dm);
- MFace *mface = dm->getTessFaceArray(dm);
- MTFace *tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
+ const MLoop *mloop = dm->getLoopArray(dm);
+ const MLoopTri *mlooptri = dm->getLoopTriArray(dm);
+ const int tottri = dm->getNumLoopTri(dm);
+ const MLoopUV *mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname);
/* Get closest edge to that subpixel on UV map */
{
@@ -2090,8 +2084,8 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
/* distances only used for comparison */
float dist_squared, t_dist_squared;
- int i, uindex[3], edge1_index, edge2_index,
- e1_index, e2_index, target_face;
+ int i, edge1_index, edge2_index,
+ e1_index, e2_index, target_tri;
float closest_point[2], lambda, dir_vec[2];
int target_uv1, target_uv2, final_pixel[2], final_index;
@@ -2100,75 +2094,88 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
pixel[0] = ((float)(px + neighX[n_index]) + 0.5f) / (float)w;
pixel[1] = ((float)(py + neighY[n_index]) + 0.5f) / (float)h;
- /* Get uv indexes for current face part */
- if (cPoint->quad) {
- uindex[0] = 0; uindex[1] = 2; uindex[2] = 3;
- }
- else {
- uindex[0] = 0; uindex[1] = 1; uindex[2] = 2;
- }
-
/*
* Find closest edge to that pixel
*/
+
/* Dist to first edge */
- e1_index = cPoint->v1; e2_index = cPoint->v2; edge1_index = uindex[0]; edge2_index = uindex[1];
- dist_squared = dist_squared_to_line_segment_v2(pixel, tface[cPoint->face_index].uv[edge1_index], tface[cPoint->face_index].uv[edge2_index]);
+ e1_index = cPoint->v1;
+ e2_index = cPoint->v2;
+ edge1_index = 0;
+ edge2_index = 1;
+ dist_squared = dist_squared_to_line_segment_v2(
+ pixel,
+ mloopuv[mlooptri[cPoint->tri_index].tri[0]].uv,
+ mloopuv[mlooptri[cPoint->tri_index].tri[1]].uv);
/* Dist to second edge */
- t_dist_squared = dist_squared_to_line_segment_v2(pixel, tface[cPoint->face_index].uv[uindex[1]], tface[cPoint->face_index].uv[uindex[2]]);
- if (t_dist_squared < dist_squared) { e1_index = cPoint->v2; e2_index = cPoint->v3; edge1_index = uindex[1]; edge2_index = uindex[2]; dist_squared = t_dist_squared; }
+ t_dist_squared = dist_squared_to_line_segment_v2(
+ pixel,
+ mloopuv[mlooptri[cPoint->tri_index].tri[1]].uv,
+ mloopuv[mlooptri[cPoint->tri_index].tri[2]].uv);
+ if (t_dist_squared < dist_squared) {
+ e1_index = cPoint->v2;
+ e2_index = cPoint->v3;
+ edge1_index = 1;
+ edge2_index = 2;
+ dist_squared = t_dist_squared;
+ }
/* Dist to third edge */
- t_dist_squared = dist_squared_to_line_segment_v2(pixel, tface[cPoint->face_index].uv[uindex[2]], tface[cPoint->face_index].uv[uindex[0]]);
- if (t_dist_squared < dist_squared) { e1_index = cPoint->v3; e2_index = cPoint->v1; edge1_index = uindex[2]; edge2_index = uindex[0]; dist_squared = t_dist_squared; }
+ t_dist_squared = dist_squared_to_line_segment_v2(
+ pixel,
+ mloopuv[mlooptri[cPoint->tri_index].tri[2]].uv,
+ mloopuv[mlooptri[cPoint->tri_index].tri[0]].uv);
+ if (t_dist_squared < dist_squared) {
+ e1_index = cPoint->v3;
+ e2_index = cPoint->v1;
+ edge1_index = 2;
+ edge2_index = 0;
+ dist_squared = t_dist_squared;
+ }
/*
* Now find another face that is linked to that edge
*/
- target_face = -1;
+ target_tri = -1;
- for (i = 0; i < numOfFaces; i++) {
+ for (i = 0; i < tottri; i++) {
/*
* Check if both edge vertices share this face
*/
- int v4 = (mface[i].v4) ? mface[i].v4 : -1;
-
- if ((e1_index == mface[i].v1 || e1_index == mface[i].v2 || e1_index == mface[i].v3 || e1_index == v4) &&
- (e2_index == mface[i].v1 || e2_index == mface[i].v2 || e2_index == mface[i].v3 || e2_index == v4))
+ if ((e1_index == mloop[mlooptri[i].tri[0]].v || e1_index == mloop[mlooptri[i].tri[1]].v || e1_index == mloop[mlooptri[i].tri[2]].v) &&
+ (e2_index == mloop[mlooptri[i].tri[0]].v || e2_index == mloop[mlooptri[i].tri[1]].v || e2_index == mloop[mlooptri[i].tri[2]].v))
{
- if (i == cPoint->face_index) continue;
+ if (i == cPoint->tri_index) continue;
- target_face = i;
+ target_tri = i;
/*
* Get edge UV index
*/
- if (e1_index == mface[i].v1) target_uv1 = 0;
- else if (e1_index == mface[i].v2) target_uv1 = 1;
- else if (e1_index == mface[i].v3) target_uv1 = 2;
- else target_uv1 = 3;
+ if (e1_index == mloop[mlooptri[i].tri[0]].v) target_uv1 = 0;
+ else if (e1_index == mloop[mlooptri[i].tri[1]].v) target_uv1 = 1;
+ else if (e1_index == mloop[mlooptri[i].tri[2]].v) target_uv1 = 2;
- if (e2_index == mface[i].v1) target_uv2 = 0;
- else if (e2_index == mface[i].v2) target_uv2 = 1;
- else if (e2_index == mface[i].v3) target_uv2 = 2;
- else target_uv2 = 3;
+ if (e2_index == mloop[mlooptri[i].tri[0]].v) target_uv2 = 0;
+ else if (e2_index == mloop[mlooptri[i].tri[1]].v) target_uv2 = 1;
+ else if (e2_index == mloop[mlooptri[i].tri[2]].v) target_uv2 = 2;
break;
}
}
/* If none found pixel is on mesh edge */
- if (target_face == -1) return ON_MESH_EDGE;
+ if (target_tri == -1) return ON_MESH_EDGE;
/*
* If target face is connected in UV space as well, just use original index
*/
- s_uv1 = (float *)tface[cPoint->face_index].uv[edge1_index];
- s_uv2 = (float *)tface[cPoint->face_index].uv[edge2_index];
- t_uv1 = (float *)tface[target_face].uv[target_uv1];
- t_uv2 = (float *)tface[target_face].uv[target_uv2];
+ s_uv1 = mloopuv[mlooptri[cPoint->tri_index].tri[edge1_index]].uv;
+ s_uv2 = mloopuv[mlooptri[cPoint->tri_index].tri[edge2_index]].uv;
+ t_uv1 = mloopuv[mlooptri[target_tri].tri[target_uv1]].uv;
+ t_uv2 = mloopuv[mlooptri[target_tri].tri[target_uv2]].uv;
//printf("connected UV : %f,%f & %f,%f - %f,%f & %f,%f\n", s_uv1[0], s_uv1[1], s_uv2[0], s_uv2[1], t_uv1[0], t_uv1[1], t_uv2[0], t_uv2[1]);
@@ -2184,15 +2191,21 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
* Find a point that is relatively at same edge position
* on this other face UV
*/
- lambda = closest_to_line_v2(closest_point, pixel, tface[cPoint->face_index].uv[edge1_index], tface[cPoint->face_index].uv[edge2_index]);
+ lambda = closest_to_line_v2(
+ closest_point, pixel,
+ mloopuv[mlooptri[cPoint->tri_index].tri[edge1_index]].uv,
+ mloopuv[mlooptri[cPoint->tri_index].tri[edge2_index]].uv);
if (lambda < 0.0f) lambda = 0.0f;
if (lambda > 1.0f) lambda = 1.0f;
- sub_v2_v2v2(dir_vec, tface[target_face].uv[target_uv2], tface[target_face].uv[target_uv1]);
+ sub_v2_v2v2(
+ dir_vec,
+ mloopuv[mlooptri[target_tri].tri[target_uv2]].uv,
+ mloopuv[mlooptri[target_tri].tri[target_uv1]].uv);
mul_v2_fl(dir_vec, lambda);
- copy_v2_v2(pixel, tface[target_face].uv[target_uv1]);
+ copy_v2_v2(pixel, mloopuv[mlooptri[target_tri].tri[target_uv1]].uv);
add_v2_v2(pixel, dir_vec);
pixel[0] = (pixel[0] * (float)w) - 0.5f;
pixel[1] = (pixel[1] * (float)h) - 0.5f;
@@ -2209,7 +2222,9 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
/* If we ended up to our origin point ( mesh has smaller than pixel sized faces) */
if (final_index == (px + w * py)) return NOT_FOUND;
/* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces) */
- if (tempPoints[final_index].face_index != target_face) return NOT_FOUND;
+ if (tempPoints[final_index].tri_index != target_tri) {
+ return NOT_FOUND;
+ }
/*
* If final point is an "edge pixel", use it's "real" neighbor instead
@@ -2236,7 +2251,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
};
int ty;
int w, h;
- int numOfFaces;
+ int tottri;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
int active_points = 0;
int error = 0;
@@ -2247,8 +2262,10 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
PaintUVPoint *tempPoints = NULL;
Vec3f *tempWeights = NULL;
- MFace *mface = NULL;
- MTFace *tface = NULL;
+ const MLoopTri *mlooptri = NULL;
+ const MLoopUV *mloopuv = NULL;
+ const MLoop *mloop = NULL;
+
Bounds2D *faceBB = NULL;
int *final_index;
int aa_samples;
@@ -2258,15 +2275,16 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ)
return setError(canvas, N_("Cannot bake non-'image sequence' formats"));
- numOfFaces = dm->getNumTessFaces(dm);
- mface = dm->getTessFaceArray(dm);
+ mloop = dm->getLoopArray(dm);
+ mlooptri = dm->getLoopTriArray(dm);
+ tottri = dm->getNumLoopTri(dm);
/* get uv map */
- CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, surface->uvlayer_name, uvname);
- tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
+ CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, surface->uvlayer_name, uvname);
+ mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname);
/* Check for validity */
- if (!tface)
+ if (!mloopuv)
return setError(canvas, N_("No UV data on canvas"));
if (surface->image_resolution < 16 || surface->image_resolution > 8192)
return setError(canvas, N_("Invalid resolution"));
@@ -2276,7 +2294,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
/*
* Start generating the surface
*/
- printf("DynamicPaint: Preparing UV surface of %ix%i pixels and %i faces.\n", w, h, numOfFaces);
+ printf("DynamicPaint: Preparing UV surface of %ix%i pixels and %i tris.\n", w, h, tottri);
/* Init data struct */
if (surface->data) dynamicPaint_freeSurfaceData(surface);
@@ -2299,24 +2317,22 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
* the pixel-inside-a-face search.
*/
if (!error) {
- faceBB = (struct Bounds2D *) MEM_mallocN(numOfFaces * sizeof(struct Bounds2D), "MPCanvasFaceBB");
+ faceBB = (struct Bounds2D *) MEM_mallocN(tottri * sizeof(struct Bounds2D), "MPCanvasFaceBB");
if (!faceBB) error = 1;
}
if (!error)
- for (ty = 0; ty < numOfFaces; ty++) {
- int numOfVert = (mface[ty].v4) ? 4 : 3;
+ for (ty = 0; ty < tottri; ty++) {
int i;
- copy_v2_v2(faceBB[ty].min, tface[ty].uv[0]);
- copy_v2_v2(faceBB[ty].max, tface[ty].uv[0]);
-
- for (i = 1; i < numOfVert; i++) {
- if (tface[ty].uv[i][0] < faceBB[ty].min[0]) faceBB[ty].min[0] = tface[ty].uv[i][0];
- if (tface[ty].uv[i][1] < faceBB[ty].min[1]) faceBB[ty].min[1] = tface[ty].uv[i][1];
- if (tface[ty].uv[i][0] > faceBB[ty].max[0]) faceBB[ty].max[0] = tface[ty].uv[i][0];
- if (tface[ty].uv[i][1] > faceBB[ty].max[1]) faceBB[ty].max[1] = tface[ty].uv[i][1];
+ copy_v2_v2(faceBB[ty].min, mloopuv[mlooptri[ty].tri[0]].uv);
+ copy_v2_v2(faceBB[ty].max, mloopuv[mlooptri[ty].tri[0]].uv);
+ for (i = 1; i < 3; i++) {
+ CLAMP_MAX(faceBB[ty].min[0], mloopuv[mlooptri[ty].tri[i]].uv[0]);
+ CLAMP_MAX(faceBB[ty].min[1], mloopuv[mlooptri[ty].tri[i]].uv[1]);
+ CLAMP_MIN(faceBB[ty].max[0], mloopuv[mlooptri[ty].tri[i]].uv[0]);
+ CLAMP_MIN(faceBB[ty].max[1], mloopuv[mlooptri[ty].tri[i]].uv[1]);
}
}
@@ -2333,13 +2349,13 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
int index = tx + w * ty;
PaintUVPoint *tPoint = (&tempPoints[index]);
- short isInside = 0; /* if point is inside a uv face */
+ bool isInside = false; /* if point is inside a uv face */
float d1[2], d2[2], d3[2], point[5][2];
float dot00, dot01, dot02, dot11, dot12, invDenom, u, v;
/* Init per pixel settings */
- tPoint->face_index = -1;
+ tPoint->tri_index = -1;
tPoint->neighbour_pixel = -1;
tPoint->pixel_index = index;
@@ -2366,9 +2382,9 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
/* Loop through samples, starting from middle point */
for (sample = 0; sample < 5; sample++) {
-
+
/* Loop through every face in the mesh */
- for (i = 0; i < numOfFaces; i++) {
+ for (i = 0; i < tottri; i++) {
/* Check uv bb */
if (faceBB[i].min[0] > (point[sample][0])) continue;
@@ -2378,9 +2394,9 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
/* Calculate point inside a triangle check
* for uv0, 1, 2 */
- sub_v2_v2v2(d1, tface[i].uv[2], tface[i].uv[0]); // uv2 - uv0
- sub_v2_v2v2(d2, tface[i].uv[1], tface[i].uv[0]); // uv1 - uv0
- sub_v2_v2v2(d3, point[sample], tface[i].uv[0]); // point - uv0
+ sub_v2_v2v2(d1, mloopuv[mlooptri[i].tri[2]].uv, mloopuv[mlooptri[i].tri[0]].uv); /* uv2 - uv0 */
+ sub_v2_v2v2(d2, mloopuv[mlooptri[i].tri[1]].uv, mloopuv[mlooptri[i].tri[0]].uv); /* uv1 - uv0 */
+ sub_v2_v2v2(d3, point[sample], mloopuv[mlooptri[i].tri[0]].uv); /* point - uv0 */
dot00 = d1[0] * d1[0] + d1[1] * d1[1];
dot01 = d1[0] * d2[0] + d1[1] * d2[1];
@@ -2393,50 +2409,20 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
- if ((u > 0) && (v > 0) && (u + v < 1)) { isInside = 1; } /* is inside a triangle */
-
- /* If collision wasn't found but the face is a quad
- * do another check for the second half */
- if ((!isInside) && mface[i].v4) {
-
- /* change d2 to test the other half */
- sub_v2_v2v2(d2, tface[i].uv[3], tface[i].uv[0]); // uv3 - uv0
-
- /* test again */
- dot00 = d1[0] * d1[0] + d1[1] * d1[1];
- dot01 = d1[0] * d2[0] + d1[1] * d2[1];
- dot02 = d1[0] * d3[0] + d1[1] * d3[1];
- dot11 = d2[0] * d2[0] + d2[1] * d2[1];
- dot12 = d2[0] * d3[0] + d2[1] * d3[1];
-
- invDenom = (dot00 * dot11 - dot01 * dot01);
- invDenom = invDenom ? 1.0f / invDenom : 1.0f;
- u = (dot11 * dot02 - dot01 * dot12) * invDenom;
- v = (dot00 * dot12 - dot01 * dot02) * invDenom;
-
- if ((u > 0) && (v > 0) && (u + v < 1)) { isInside = 2; } /* is inside the second half of the quad */
-
- }
+ if ((u > 0) && (v > 0) && (u + v < 1)) { isInside = true; } /* is inside a triangle */
/*
* If point was inside the face
*/
- if (isInside != 0) {
+ if (isInside) {
float uv1co[2], uv2co[2], uv3co[2], uv[2];
int j;
/* Get triagnle uvs */
- if (isInside == 1) {
- copy_v2_v2(uv1co, tface[i].uv[0]);
- copy_v2_v2(uv2co, tface[i].uv[1]);
- copy_v2_v2(uv3co, tface[i].uv[2]);
- }
- else {
- copy_v2_v2(uv1co, tface[i].uv[0]);
- copy_v2_v2(uv2co, tface[i].uv[2]);
- copy_v2_v2(uv3co, tface[i].uv[3]);
- }
+ copy_v2_v2(uv1co, mloopuv[mlooptri[i].tri[0]].uv);
+ copy_v2_v2(uv2co, mloopuv[mlooptri[i].tri[1]].uv);
+ copy_v2_v2(uv3co, mloopuv[mlooptri[i].tri[2]].uv);
/* Add b-weights per anti-aliasing sample */
for (j = 0; j < aa_samples; j++) {
@@ -2447,13 +2433,12 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
}
/* Set surface point face values */
- tPoint->face_index = i; /* face index */
- tPoint->quad = (isInside == 2) ? 1 : 0; /* quad or tri part*/
+ tPoint->tri_index = i;
/* save vertex indexes */
- tPoint->v1 = mface[i].v1;
- tPoint->v2 = (isInside == 2) ? mface[i].v3 : mface[i].v2;
- tPoint->v3 = (isInside == 2) ? mface[i].v4 : mface[i].v3;
+ tPoint->v1 = mloop[mlooptri[i].tri[0]].v;
+ tPoint->v2 = mloop[mlooptri[i].tri[1]].v;
+ tPoint->v3 = mloop[mlooptri[i].tri[2]].v;
sample = 5; /* make sure we exit sample loop as well */
break;
@@ -2477,7 +2462,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
PaintUVPoint *tPoint = (&tempPoints[index]);
/* If point isn't't on canvas mesh */
- if (tPoint->face_index == -1) {
+ if (tPoint->tri_index == -1) {
int u_min, u_max, v_min, v_max;
int u, v, ind;
float point[2];
@@ -2499,22 +2484,15 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
ind = (tx + u) + w * (ty + v);
/* if neighbor has index */
- if (tempPoints[ind].face_index != -1) {
+ if (tempPoints[ind].tri_index != -1) {
float uv1co[2], uv2co[2], uv3co[2], uv[2];
- int i = tempPoints[ind].face_index, j;
+ int i = tempPoints[ind].tri_index, j;
/* Now calculate pixel data for this pixel as it was on polygon surface */
- if (!tempPoints[ind].quad) {
- copy_v2_v2(uv1co, tface[i].uv[0]);
- copy_v2_v2(uv2co, tface[i].uv[1]);
- copy_v2_v2(uv3co, tface[i].uv[2]);
- }
- else {
- copy_v2_v2(uv1co, tface[i].uv[0]);
- copy_v2_v2(uv2co, tface[i].uv[2]);
- copy_v2_v2(uv3co, tface[i].uv[3]);
- }
+ copy_v2_v2(uv1co, mloopuv[mlooptri[i].tri[0]].uv);
+ copy_v2_v2(uv2co, mloopuv[mlooptri[i].tri[1]].uv);
+ copy_v2_v2(uv3co, mloopuv[mlooptri[i].tri[2]].uv);
/* Add b-weights per anti-aliasing sample */
for (j = 0; j < aa_samples; j++) {
@@ -2525,13 +2503,12 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
}
/* Set values */
- tPoint->neighbour_pixel = ind; // face index
- tPoint->quad = tempPoints[ind].quad; // quad or tri
+ tPoint->neighbour_pixel = ind; /* tri index */
/* save vertex indexes */
- tPoint->v1 = mface[i].v1;
- tPoint->v2 = (tPoint->quad) ? mface[i].v3 : mface[i].v2;
- tPoint->v3 = (tPoint->quad) ? mface[i].v4 : mface[i].v3;
+ tPoint->v1 = mloop[mlooptri[i].tri[0]].v;
+ tPoint->v2 = mloop[mlooptri[i].tri[1]].v;
+ tPoint->v3 = mloop[mlooptri[i].tri[2]].v;
u = u_max + 1; /* make sure we exit outer loop as well */
break;
@@ -2550,10 +2527,12 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
int tx;
for (tx = 0; tx < w; tx++) {
int index = tx + w * ty;
- PaintUVPoint *tPoint = (&tempPoints[index]);
+ PaintUVPoint *tPoint = &tempPoints[index];
- if (tPoint->face_index == -1 && tPoint->neighbour_pixel != -1) tPoint->face_index = tempPoints[tPoint->neighbour_pixel].face_index;
- if (tPoint->face_index != -1) active_points++;
+ if (tPoint->tri_index == -1 && tPoint->neighbour_pixel != -1)
+ tPoint->tri_index = tempPoints[tPoint->neighbour_pixel].tri_index;
+ if (tPoint->tri_index != -1)
+ active_points++;
}
}
@@ -2564,7 +2543,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
/* Create a temporary array of final indexes (before unassigned
* pixels have been dropped) */
for (i = 0; i < w * h; i++) {
- if (tempPoints[i].face_index != -1) {
+ if (tempPoints[i].tri_index != -1) {
final_index[i] = cursor;
cursor++;
}
@@ -2581,7 +2560,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
for (tx = 0; tx < w; tx++) {
int i, index = tx + w * ty;
- if (tempPoints[index].face_index != -1) {
+ if (tempPoints[index].tri_index != -1) {
ed->n_index[final_index[index]] = n_pos;
ed->n_num[final_index[index]] = 0;
@@ -2635,7 +2614,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
sData->format_data = f_data;
for (index = 0; index < (w * h); index++) {
- if (tempPoints[index].face_index != -1) {
+ if (tempPoints[index].tri_index != -1) {
memcpy(&f_data->uv_p[cursor], &tempPoints[index], sizeof(PaintUVPoint));
memcpy(&f_data->barycentricWeights[cursor * aa_samples], &tempWeights[index * aa_samples], sizeof(Vec3f) * aa_samples);
cursor++;
@@ -2671,9 +2650,9 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
/* Every pixel that is assigned as "edge pixel" gets blue color */
if (uvPoint->neighbour_pixel != -1) pPoint->color[2] = 1.0f;
/* and every pixel that finally got an polygon gets red color */
- if (uvPoint->face_index != -1) pPoint->color[0] = 1.0f;
+ if (uvPoint->tri_index != -1) pPoint->color[0] = 1.0f;
/* green color shows pixel face index hash */
- if (uvPoint->face_index != -1) pPoint->color[1] = (float)(uvPoint->face_index % 255) / 256.0f;
+ if (uvPoint->tri_index != -1) pPoint->color[1] = (float)(uvPoint->tri_index % 255) / 256.0f;
}
#endif
@@ -2741,7 +2720,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam
PaintPoint *point = &((PaintPoint *)sData->type_data)[index];
/* blend wet and dry layers */
- blendColors(point->color, point->alpha, point->e_color, point->e_alpha, &ibuf->rect_float[pos]);
+ blendColors(point->color, point->color[3], point->e_color, point->e_color[3], &ibuf->rect_float[pos]);
/* Multiply color by alpha if enabled */
if (surface->flags & MOD_DPAINT_MULALPHA) {
@@ -2858,17 +2837,20 @@ static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats)
/*
* Get material diffuse color and alpha (including linked textures) in given coordinates
*/
-static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb,
- const float volume_co[3], const float surface_co[3],
- int faceIndex, short isQuad, DerivedMesh *orcoDm)
+static void dynamicPaint_doMaterialTex(
+ BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb,
+ const float volume_co[3], const float surface_co[3],
+ int triIndex, DerivedMesh *orcoDm)
{
Material *mat = bMats->mat;
- MFace *mface = orcoDm->getTessFaceArray(orcoDm);
+
+ const MLoopTri *mlooptri = orcoDm->getLoopTriArray(orcoDm);
+ const MPoly *mpoly = orcoDm->getPolyArray(orcoDm);
/* If no material defined, use the one assigned to the mesh face */
if (mat == NULL) {
if (bMats->ob_mats) {
- int mat_nr = mface[faceIndex].mat_nr;
+ int mat_nr = mpoly[mlooptri[triIndex].poly].mat_nr;
if (mat_nr >= (*give_totcolp(brushOb))) return;
mat = bMats->ob_mats[mat_nr];
if (mat == NULL) return; /* No material assigned */
@@ -2877,88 +2859,69 @@ static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], fl
return;
}
}
-
- RE_sample_material_color(mat, color, alpha, volume_co, surface_co, faceIndex, isQuad, orcoDm, brushOb);
+ RE_sample_material_color(mat, color, alpha, volume_co, surface_co, triIndex, orcoDm, brushOb);
}
/***************************** Ray / Nearest Point Utils ******************************/
-/* A modified callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_faces.
+/* A modified callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_looptri.
* userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
*
* To optimize brush detection speed this doesn't calculate hit coordinates or normal.
- * If ray hit the second half of a quad, no[0] is set to 1.0f.
*/
-static void mesh_faces_spherecast_dp(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+static void mesh_tris_spherecast_dp(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata;
const MVert *vert = data->vert;
- const MFace *face = data->face + index;
- short quad = 0;
-
- const float *t0, *t1, *t2, *t3;
- t0 = vert[face->v1].co;
- t1 = vert[face->v2].co;
- t2 = vert[face->v3].co;
- t3 = face->v4 ? vert[face->v4].co : NULL;
-
- do {
- float dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2);
-
- if (dist >= 0 && dist < hit->dist) {
- hit->index = index;
- hit->dist = dist;
- hit->no[0] = (quad) ? 1.0f : 0.0f;
- }
+ const MLoopTri *mlooptri = data->looptri;
+ const MLoop *mloop = data->loop;
+
+ const float *t0, *t1, *t2;
+ float dist;
- t1 = t2;
- t2 = t3;
- t3 = NULL;
- quad = 1;
+ t0 = vert[mloop[mlooptri[index].tri[0]].v].co;
+ t1 = vert[mloop[mlooptri[index].tri[1]].v].co;
+ t2 = vert[mloop[mlooptri[index].tri[2]].v].co;
+
+ dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2);
+
+ if (dist >= 0 && dist < hit->dist) {
+ hit->index = index;
+ hit->dist = dist;
+ hit->no[0] = 0.0f;
+ }
- } while (t2);
}
-/* A modified callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces.
+/* A modified callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_looptri.
* userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
*
* To optimize brush detection speed this doesn't calculate hit normal.
- * If ray hit the second half of a quad, no[0] is set to 1.0f, else 0.0f
*/
-static void mesh_faces_nearest_point_dp(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
+static void mesh_tris_nearest_point_dp(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata;
const MVert *vert = data->vert;
- const MFace *face = data->face + index;
- short quad = 0;
-
- const float *t0, *t1, *t2, *t3;
- t0 = vert[face->v1].co;
- t1 = vert[face->v2].co;
- t2 = vert[face->v3].co;
- t3 = face->v4 ? vert[face->v4].co : NULL;
-
- do {
- float nearest_tmp[3], dist_sq;
-
- closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2);
- dist_sq = len_squared_v3v3(co, nearest_tmp);
-
- if (dist_sq < nearest->dist_sq) {
- nearest->index = index;
- nearest->dist_sq = dist_sq;
- copy_v3_v3(nearest->co, nearest_tmp);
- nearest->no[0] = (quad) ? 1.0f : 0.0f;
- }
-
- t1 = t2;
- t2 = t3;
- t3 = NULL;
- quad = 1;
-
- } while (t2);
+ const MLoopTri *mlooptri = data->looptri;
+ const MLoop *mloop = data->loop;
+ float nearest_tmp[3], dist_sq;
+
+ const float *t0, *t1, *t2;
+ t0 = vert[mloop[mlooptri[index].tri[0]].v].co;
+ t1 = vert[mloop[mlooptri[index].tri[1]].v].co;
+ t2 = vert[mloop[mlooptri[index].tri[2]].v].co;
+
+ closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2);
+ dist_sq = len_squared_v3v3(co, nearest_tmp);
+
+ if (dist_sq < nearest->dist_sq) {
+ nearest->index = index;
+ nearest->dist_sq = dist_sq;
+ copy_v3_v3(nearest->co, nearest_tmp);
+ nearest->no[0] = 0.0f;
+ }
}
@@ -2986,23 +2949,23 @@ static void dynamicPaint_mixPaintColors(
float temp_alpha = (*paintAlpha) * ((paintFlags & MOD_DPAINT_ABS_ALPHA) ? 1.0f : (*timescale));
/* mix brush color with wet layer color */
- blendColors(pPoint->e_color, pPoint->e_alpha, paintColor, temp_alpha, mix);
+ blendColors(pPoint->e_color, pPoint->e_color[3], paintColor, temp_alpha, mix);
copy_v3_v3(pPoint->e_color, mix);
/* mix wetness and alpha depending on selected alpha mode */
if (paintFlags & MOD_DPAINT_ABS_ALPHA) {
/* update values to the brush level unless theyre higher already */
- if (pPoint->e_alpha < (*paintAlpha)) pPoint->e_alpha = (*paintAlpha);
- if (pPoint->wetness < (*paintWetness)) pPoint->wetness = (*paintWetness);
+ CLAMP_MIN(pPoint->e_color[3], *paintAlpha);
+ CLAMP_MIN(pPoint->wetness, *paintWetness);
}
else {
float wetness = (*paintWetness);
CLAMP(wetness, 0.0f, 1.0f);
- pPoint->e_alpha = mix[3];
+ pPoint->e_color[3] = mix[3];
pPoint->wetness = pPoint->wetness * (1.0f - wetness) + wetness;
}
- if (pPoint->wetness < MIN_WETNESS) pPoint->wetness = MIN_WETNESS;
+ CLAMP_MIN(pPoint->wetness, MIN_WETNESS);
pPoint->state = DPAINT_PAINT_NEW;
}
@@ -3017,23 +2980,23 @@ static void dynamicPaint_mixPaintColors(
* but maintain alpha ratio
*/
if (paintFlags & MOD_DPAINT_ABS_ALPHA) {
- a_highest = (pPoint->e_alpha > pPoint->alpha) ? pPoint->e_alpha : pPoint->alpha;
+ a_highest = max_ff(pPoint->color[3], pPoint->e_color[3]);
if (a_highest > invFact) {
a_ratio = invFact / a_highest;
- pPoint->e_alpha *= a_ratio;
- pPoint->alpha *= a_ratio;
+ pPoint->e_color[3] *= a_ratio;
+ pPoint->color[3] *= a_ratio;
}
}
else {
- pPoint->e_alpha -= (*paintAlpha) * (*timescale);
- if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f;
- pPoint->alpha -= (*paintAlpha) * (*timescale);
- if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f;
+ pPoint->e_color[3] -= (*paintAlpha) * (*timescale);
+ CLAMP_MIN(pPoint->e_color[3], 0.0f);
+ pPoint->color[3] -= (*paintAlpha) * (*timescale);
+ CLAMP_MIN(pPoint->color[3], 0.0f);
}
- wetness = (1.0f - (*paintWetness)) * pPoint->e_alpha;
- if (pPoint->wetness > wetness) pPoint->wetness = wetness;
+ wetness = (1.0f - (*paintWetness)) * pPoint->e_color[3];
+ CLAMP_MAX(pPoint->wetness, wetness);
}
}
@@ -3286,7 +3249,8 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
DerivedMesh *dm = NULL;
Vec3f *brushVelocity = NULL;
MVert *mvert = NULL;
- MFace *mface = NULL;
+ const MLoopTri *mlooptri = NULL;
+ const MLoop *mloop = NULL;
if (brush->flags & MOD_DPAINT_USES_VELOCITY)
dynamicPaint_brushMeshCalculateVelocity(scene, brushOb, brush, &brushVelocity, timescale);
@@ -3303,7 +3267,8 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
dm = CDDM_copy(brush->dm);
mvert = dm->getVertArray(dm);
- mface = dm->getTessFaceArray(dm);
+ mlooptri = dm->getLoopTriArray(dm);
+ mloop = dm->getLoopArray(dm);
numOfVerts = dm->getNumVerts(dm);
/* Transform collider vertices to global space
@@ -3336,7 +3301,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
/* check bounding box collision */
if (grid && meshBrush_boundsIntersect(&grid->grid_bounds, &mesh_bb, brush, brush_radius)) {
/* Build a bvh tree from transformed vertices */
- if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 8)) {
+ if (bvhtree_from_mesh_looptri(&treeData, dm, 0.0f, 4, 8)) {
int c_index;
int total_cells = grid->dim[0] * grid->dim[1] * grid->dim[2];
@@ -3385,8 +3350,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
/* hit data */
float hitCoord[3];
- int hitFace = -1;
- short hitQuad = 0;
+ int hitTri = -1;
/* Supersampling factor */
if (samples > 1 && surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
@@ -3408,16 +3372,19 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
/* Check volume collision */
if (brush->collision == MOD_DPAINT_COL_VOLUME || brush->collision == MOD_DPAINT_COL_VOLDIST)
- if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1) {
+ if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_tris_spherecast_dp, &treeData) != -1) {
/* We hit a triangle, now check if collision point normal is facing the point */
/* For optimization sake, hit point normal isn't calculated in ray cast loop */
- int v1 = mface[hit.index].v1, v2 = mface[hit.index].v2, v3 = mface[hit.index].v3, quad = (hit.no[0] == 1.0f);
+ const int vtri[3] = {
+ mloop[mlooptri[hit.index].tri[0]].v,
+ mloop[mlooptri[hit.index].tri[1]].v,
+ mloop[mlooptri[hit.index].tri[2]].v,
+ };
float dot;
- if (quad) { v2 = mface[hit.index].v3; v3 = mface[hit.index].v4; }
- normal_tri_v3(hit.no, mvert[v1].co, mvert[v2].co, mvert[v3].co);
- dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2];
+ normal_tri_v3(hit.no, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co);
+ dot = dot_v3v3(ray_dir, hit.no);
/* If ray and hit face normal are facing same direction
* hit point is inside a closed mesh. */
@@ -3431,7 +3398,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
hit.index = -1;
hit.dist = 9999;
- BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData);
+ BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_tris_spherecast_dp, &treeData);
if (hit.index != -1) {
/* Add factor on supersample filter */
@@ -3441,8 +3408,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
/* Mark hit info */
madd_v3_v3v3fl(hitCoord, ray_start, ray_dir, hit.dist); /* Calculate final hit coordinates */
depth += dist * sample_factor;
- hitFace = f_index;
- hitQuad = quad;
+ hitTri = f_index;
}
}
}
@@ -3453,19 +3419,17 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
{
float proxDist = -1.0f;
float hitCo[3] = {0.0f, 0.0f, 0.0f};
- short hQuad;
- int face;
+ int tri;
/* if inverse prox and no hit found, skip this sample */
if (inner_proximity && !hit_found) continue;
/* If pure distance proximity, find the nearest point on the mesh */
if (!(brush->flags & MOD_DPAINT_PROX_PROJECT)) {
- if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, mesh_faces_nearest_point_dp, &treeData) != -1) {
+ if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, mesh_tris_nearest_point_dp, &treeData) != -1) {
proxDist = sqrtf(nearest.dist_sq);
copy_v3_v3(hitCo, nearest.co);
- hQuad = (nearest.no[0] == 1.0f);
- face = nearest.index;
+ tri = nearest.index;
}
}
else { /* else cast a ray in defined projection direction */
@@ -3485,11 +3449,10 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
hit.dist = brush_radius;
/* Do a face normal directional raycast, and use that distance */
- if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, proj_ray, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1) {
+ if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, proj_ray, 0.0f, &hit, mesh_tris_spherecast_dp, &treeData) != -1) {
proxDist = hit.dist;
madd_v3_v3v3fl(hitCo, ray_start, proj_ray, hit.dist); /* Calculate final hit coordinates */
- hQuad = (hit.no[0] == 1.0f);
- face = hit.index;
+ tri = hit.index;
}
}
@@ -3503,10 +3466,9 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
hit_found = HIT_PROXIMITY;
/* if no volume hit, use prox point face info */
- if (hitFace == -1) {
+ if (hitTri == -1) {
copy_v3_v3(hitCoord, hitCo);
- hitQuad = hQuad;
- hitFace = face;
+ hitTri = tri;
}
}
}
@@ -3547,16 +3509,10 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
float brushPointVelocity[3];
float velocity[3];
- if (!hitQuad) {
- v1 = mface[hitFace].v1;
- v2 = mface[hitFace].v2;
- v3 = mface[hitFace].v3;
- }
- else {
- v1 = mface[hitFace].v2;
- v2 = mface[hitFace].v3;
- v3 = mface[hitFace].v4;
- }
+ v1 = mloop[mlooptri[hitTri].tri[0]].v;
+ v2 = mloop[mlooptri[hitTri].tri[1]].v;
+ v3 = mloop[mlooptri[hitTri].tri[2]].v;
+
/* calculate barycentric weights for hit point */
interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, hitCoord);
@@ -3601,7 +3557,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
/* Get material+textures color on hit point if required */
if (brush_usesMaterial(brush, scene))
- dynamicPaint_doMaterialTex(bMats, sampleColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index] + ss].v, hitCoord, hitFace, hitQuad, brush->dm);
+ dynamicPaint_doMaterialTex(bMats, sampleColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index] + ss].v, hitCoord, hitTri, brush->dm);
/* Sample proximity colorband if required */
if ((hit_found == HIT_PROXIMITY) && (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP)) {
@@ -3961,7 +3917,7 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po
copy_v3_v3(hit_coord, mvert[0].co);
mul_m4_v3(brushOb->obmat, hit_coord);
- dynamicPaint_doMaterialTex(bMats, paintColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index]].v, hit_coord, 0, 0, brush->dm);
+ dynamicPaint_doMaterialTex(bMats, paintColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index]].v, hit_coord, 0, brush->dm);
}
/* color ramp */
@@ -4190,15 +4146,15 @@ static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, DynamicPaintBrus
if (dir_dot <= 0.0f) continue;
dir_factor = dir_dot * speed_scale;
- if (dir_factor > brush->smudge_strength) dir_factor = brush->smudge_strength;
+ CLAMP_MAX(dir_factor, brush->smudge_strength);
/* mix new color and alpha */
- mixColors(ePoint->color, ePoint->alpha, pPoint->color, pPoint->alpha, dir_factor);
- ePoint->alpha = ePoint->alpha * (1.0f - dir_factor) + pPoint->alpha * dir_factor;
+ mixColors(ePoint->color, ePoint->color[3], pPoint->color, pPoint->color[3], dir_factor);
+ ePoint->color[3] = ePoint->color[3] * (1.0f - dir_factor) + pPoint->color[3] * dir_factor;
/* smudge "wet layer" */
- mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, pPoint->e_alpha, dir_factor);
- ePoint->e_alpha = ePoint->e_alpha * (1.0f - dir_factor) + pPoint->e_alpha * dir_factor;
+ mixColors(ePoint->e_color, ePoint->e_color[3], pPoint->e_color, pPoint->e_color[3], dir_factor);
+ ePoint->e_color[3] = ePoint->e_color[3] * (1.0f - dir_factor) + pPoint->e_color[3] * dir_factor;
pPoint->wetness *= (1.0f - dir_factor);
}
}
@@ -4337,7 +4293,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
float color_mix = (MIN3(ePoint->wetness, pPoint->wetness, 1.0f)) * 0.25f * surface->color_spread_speed;
/* do color mixing */
- if (color_mix) mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, ePoint->e_alpha, color_mix);
+ if (color_mix) mixColors(pPoint->e_color, pPoint->e_color[3], ePoint->e_color, ePoint->e_color[3], color_mix);
/* Only continue if surrounding point has higher wetness */
if (ePoint->wetness < pPoint->wetness || ePoint->wetness < MIN_WETNESS) continue;
@@ -4347,7 +4303,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
/* mix new wetness and color */
pPoint->wetness = (1.0f - w_factor) * pPoint->wetness + w_factor * ePoint->wetness;
- pPoint->e_alpha = mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, ePoint->e_alpha, w_factor);
+ pPoint->e_color[3] = mixColors(pPoint->e_color, pPoint->e_color[3], ePoint->e_color, ePoint->e_color[3], w_factor);
}
}
}
@@ -4374,28 +4330,28 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
PaintPoint *ePoint = &prevPoint[sData->adj_data->n_target[n_index]];
float a_factor, ea_factor, w_factor;
- totalAlpha += ePoint->e_alpha;
+ totalAlpha += ePoint->e_color[3];
/* Check if neighboring point has lower alpha,
* if so, decrease this point's alpha as well*/
- if (pPoint->alpha <= 0.0f && pPoint->e_alpha <= 0.0f && pPoint->wetness <= 0.0f) continue;
+ if (pPoint->color[3] <= 0.0f && pPoint->e_color[3] <= 0.0f && pPoint->wetness <= 0.0f) continue;
/* decrease factor for dry paint alpha */
- a_factor = (1.0f - ePoint->alpha) / numOfNeighs * (pPoint->alpha - ePoint->alpha) * speed_scale;
- if (a_factor < 0.0f) a_factor = 0.0f;
+ a_factor = (1.0f - ePoint->color[3]) / numOfNeighs * (pPoint->color[3] - ePoint->color[3]) * speed_scale;
+ CLAMP_MIN(a_factor, 0.0f);
/* decrease factor for wet paint alpha */
- ea_factor = (1.0f - ePoint->e_alpha) / 8 * (pPoint->e_alpha - ePoint->e_alpha) * speed_scale;
- if (ea_factor < 0.0f) ea_factor = 0.0f;
+ ea_factor = (1.0f - ePoint->e_color[3]) / 8 * (pPoint->e_color[3] - ePoint->e_color[3]) * speed_scale;
+ CLAMP_MIN(ea_factor, 0.0f);
/* decrease factor for paint wetness */
w_factor = (1.0f - ePoint->wetness) / 8 * (pPoint->wetness - ePoint->wetness) * speed_scale;
- if (w_factor < 0.0f) w_factor = 0.0f;
+ CLAMP_MIN(w_factor, 0.0f);
- pPoint->alpha -= a_factor;
- if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f;
- pPoint->e_alpha -= ea_factor;
- if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f;
+ pPoint->color[3] -= a_factor;
+ CLAMP_MIN(pPoint->color[3], 0.0f);
+ pPoint->e_color[3] -= ea_factor;
+ CLAMP_MIN(pPoint->e_color[3], 0.0f);
pPoint->wetness -= w_factor;
- if (pPoint->wetness < 0.0f) pPoint->wetness = 0.0f;
+ CLAMP_MIN(pPoint->wetness, 0.0f);
}
}
}
@@ -4437,7 +4393,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
if (dir_dot <= 0.0f) continue;
dir_factor = dir_dot * MIN2(speed_scale, 1.0f) * w_factor;
- if (dir_factor > 0.5f) dir_factor = 0.5f;
+ CLAMP_MAX(dir_factor, 0.5f);
/* mix new wetness */
ePoint->wetness += dir_factor;
@@ -4446,12 +4402,11 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
/* mix new color */
a_factor = dir_factor / pPoint_prev->wetness;
CLAMP(a_factor, 0.0f, 1.0f);
- mixColors(ePoint->e_color, ePoint->e_alpha, pPoint_prev->e_color, pPoint_prev->e_alpha, a_factor);
+ mixColors(ePoint->e_color, ePoint->e_color[3], pPoint_prev->e_color, pPoint_prev->e_color[3], a_factor);
/* dripping is supposed to preserve alpha level */
- if (pPoint_prev->e_alpha > ePoint->e_alpha) {
- ePoint->e_alpha += a_factor * pPoint_prev->e_alpha;
- if (ePoint->e_alpha > pPoint_prev->e_alpha)
- ePoint->e_alpha = pPoint_prev->e_alpha;
+ if (pPoint_prev->e_color[3] > ePoint->e_color[3]) {
+ ePoint->e_color[3] += a_factor * pPoint_prev->e_color[3];
+ CLAMP_MAX(ePoint->e_color[3], pPoint_prev->e_color[3]);
}
/* decrease paint wetness on current point */
@@ -4610,21 +4565,21 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time
* Slowly "shift" paint from wet layer to dry layer as it drys:
*/
/* make sure alpha values are within proper range */
- CLAMP(pPoint->alpha, 0.0f, 1.0f);
- CLAMP(pPoint->e_alpha, 0.0f, 1.0f);
+ CLAMP(pPoint->color[3], 0.0f, 1.0f);
+ CLAMP(pPoint->e_color[3], 0.0f, 1.0f);
/* get current final blended color of these layers */
- blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color);
+ blendColors(pPoint->color, pPoint->color[3], pPoint->e_color, pPoint->e_color[3], f_color);
/* reduce wet layer alpha by dry factor */
- pPoint->e_alpha *= dry_ratio;
+ pPoint->e_color[3] *= dry_ratio;
/* now calculate new alpha for dry layer that keeps final blended color unchanged */
- pPoint->alpha = (f_color[3] - pPoint->e_alpha) / (1.0f - pPoint->e_alpha);
+ pPoint->color[3] = (f_color[3] - pPoint->e_color[3]) / (1.0f - pPoint->e_color[3]);
/* for each rgb component, calculate a new dry layer color that keeps the final blend color
* with these new alpha values. (wet layer color doesnt change)*/
- if (pPoint->alpha) {
+ if (pPoint->color[3]) {
for (i = 0; i < 3; i++) {
- pPoint->color[i] = (f_color[i] * f_color[3] - pPoint->e_color[i] * pPoint->e_alpha) / (pPoint->alpha * (1.0f - pPoint->e_alpha));
+ pPoint->color[i] = (f_color[i] * f_color[3] - pPoint->e_color[i] * pPoint->e_color[3]) / (pPoint->color[3] * (1.0f - pPoint->e_color[3]));
}
}
}
@@ -4634,22 +4589,21 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time
/* in case of just dryed paint, just mix it to the dry layer and mark it empty */
else if (pPoint->state > 0) {
float f_color[4];
- blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color);
- copy_v3_v3(pPoint->color, f_color);
- pPoint->alpha = f_color[3];
+ blendColors(pPoint->color, pPoint->color[3], pPoint->e_color, pPoint->e_color[3], f_color);
+ copy_v4_v4(pPoint->color, f_color);
/* clear wet layer */
pPoint->wetness = 0.0f;
- pPoint->e_alpha = 0.0f;
+ pPoint->e_color[3] = 0.0f;
pPoint->state = DPAINT_PAINT_DRY;
}
}
if (surface->flags & MOD_DPAINT_DISSOLVE) {
- value_dissolve(&pPoint->alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG));
- if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f;
+ value_dissolve(&pPoint->color[3], surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG));
+ CLAMP_MIN(pPoint->color[3], 0.0f);
- value_dissolve(&pPoint->e_alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG));
- if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f;
+ value_dissolve(&pPoint->e_color[3], surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG));
+ CLAMP_MIN(pPoint->e_color[3], 0.0f);
}
}
/* dissolve for float types */
@@ -4661,7 +4615,7 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time
float *point = &((float *)sData->type_data)[index];
/* log or linear */
value_dissolve(point, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG));
- if (*point < 0.0f) *point = 0.0f;
+ CLAMP_MIN(*point, 0.0f);
}
}
}