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:
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_interp.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c213
1 files changed, 101 insertions, 112 deletions
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 6e468bf44f2..f51013c3f1c 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -197,7 +197,7 @@ void BM_face_interp_from_face_ex(
if (do_vertex) {
CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data);
}
- } while (i++, (l_iter = l_iter->next) != l_first);
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
}
void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex)
@@ -221,7 +221,7 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, con
mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
blocks_l[i] = l_iter->head.data;
if (do_vertex) blocks_v[i] = l_iter->v->head.data;
- } while (i++, (l_iter = l_iter->next) != l_first);
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
BM_face_interp_from_face_ex(bm, f_dst, f_src, do_vertex,
blocks_l, blocks_v, cos_2d, axis_mat);
@@ -242,18 +242,25 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, con
* </pre>
*/
static int compute_mdisp_quad(
- BMLoop *l, float v1[3], float v2[3], float v3[3], float v4[3],
+ const BMLoop *l, const float l_f_center[3],
+ float v1[3], float v2[3], float v3[3], float v4[3],
float e1[3], float e2[3])
{
- float cent[3], n[3], p[3];
-
- /* computer center */
- BM_face_calc_center_mean(l->f, cent);
+ float n[3], p[3];
+
+#ifndef NDEBUG
+ {
+ float cent[3];
+ /* computer center */
+ BM_face_calc_center_mean(l->f, cent);
+ BLI_assert(equals_v3v3(cent, l_f_center));
+ }
+#endif
mid_v3_v3v3(p, l->prev->v->co, l->v->co);
mid_v3_v3v3(n, l->next->v->co, l->v->co);
- copy_v3_v3(v1, cent);
+ copy_v3_v3(v1, l_f_center);
copy_v3_v3(v2, p);
copy_v3_v3(v3, l->v->co);
copy_v3_v3(v4, n);
@@ -264,52 +271,13 @@ static int compute_mdisp_quad(
return 1;
}
-/* funnily enough, I think this is identical to face_to_crn_interp, heh */
-static float quad_coord(const float aa[3], const float bb[3], const float cc[3], const float dd[3], int a1, int a2)
-{
- float x, y, z, f1;
- float div;
-
- x = aa[a1] * cc[a2] - cc[a1] * aa[a2];
- y = aa[a1] * dd[a2] + bb[a1] * cc[a2] - cc[a1] * bb[a2] - dd[a1] * aa[a2];
- z = bb[a1] * dd[a2] - dd[a1] * bb[a2];
-
- div = 2.0f * (x - y + z);
-
- if (fabsf(div) > FLT_EPSILON * 10.0f) {
- const float f_tmp = sqrtf(y * y - 4.0f * x * z);
-
- f1 = min_ff(fabsf(( f_tmp - y + 2.0f * z) / div),
- fabsf((-f_tmp - y + 2.0f * z) / div));
-
- CLAMP_MAX(f1, 1.0f + FLT_EPSILON);
- }
- else {
- f1 = -z / (y - 2 * z);
- CLAMP(f1, 0.0f, 1.0f + FLT_EPSILON);
-
- if (isnan(f1) || f1 > 1.0f || f1 < 0.0f) {
- int i;
-
- for (i = 0; i < 2; i++) {
- if (fabsf(aa[i]) < FLT_EPSILON * 100.0f)
- return aa[(i + 1) % 2] / fabsf(bb[(i + 1) % 2] - aa[(i + 1) % 2]);
- if (fabsf(cc[i]) < FLT_EPSILON * 100.0f)
- return cc[(i + 1) % 2] / fabsf(dd[(i + 1) % 2] - cc[(i + 1) % 2]);
- }
- }
- }
-
- return f1;
-}
-
-static int quad_co(
- float *r_x, float *r_y,
+static bool quad_co(
const float v1[3], const float v2[3], const float v3[3], const float v4[3],
- const float p[3], const float n[3])
+ const float p[3], const float n[3],
+ float r_uv[2])
{
float projverts[5][3], n2[3];
- float dprojverts[4][3], origin[3] = {0.0f, 0.0f, 0.0f};
+ float origin[2] = {0.0f, 0.0f};
int i;
/* project points into 2d along normal */
@@ -322,7 +290,7 @@ static int quad_co(
normal_quad_v3(n2, projverts[0], projverts[1], projverts[2], projverts[3]);
if (dot_v3v3(n, n2) < -FLT_EPSILON) {
- return 0;
+ return false;
}
/* rotate */
@@ -330,50 +298,45 @@ static int quad_co(
/* subtract origin */
for (i = 0; i < 4; i++) {
- sub_v3_v3(projverts[i], projverts[4]);
+ sub_v2_v2(projverts[i], projverts[4]);
}
-
- copy_v3_v3(dprojverts[0], projverts[0]);
- copy_v3_v3(dprojverts[1], projverts[1]);
- copy_v3_v3(dprojverts[2], projverts[2]);
- copy_v3_v3(dprojverts[3], projverts[3]);
- if (!isect_point_quad_v2(origin, dprojverts[0], dprojverts[1], dprojverts[2], dprojverts[3])) {
- return 0;
+ if (!isect_point_quad_v2(origin, projverts[0], projverts[1], projverts[2], projverts[3])) {
+ return false;
}
-
- *r_y = quad_coord(dprojverts[1], dprojverts[0], dprojverts[2], dprojverts[3], 0, 1);
- *r_x = quad_coord(dprojverts[2], dprojverts[1], dprojverts[3], dprojverts[0], 0, 1);
- return 1;
+ resolve_quad_uv_v2(r_uv, origin, projverts[0], projverts[3], projverts[2], projverts[1]);
+
+ return true;
}
static void mdisp_axis_from_quad(
float v1[3], float v2[3], float UNUSED(v3[3]), float v4[3],
- float axis_x[3], float axis_y[3])
+ float r_axis_x[3], float r_axis_y[3])
{
- sub_v3_v3v3(axis_x, v4, v1);
- sub_v3_v3v3(axis_y, v2, v1);
+ sub_v3_v3v3(r_axis_x, v4, v1);
+ sub_v3_v3v3(r_axis_y, v2, v1);
- normalize_v3(axis_x);
- normalize_v3(axis_y);
+ normalize_v3(r_axis_x);
+ normalize_v3(r_axis_y);
}
/* tl is loop to project onto, l is loop whose internal displacement, co, is being
* projected. x and y are location in loop's mdisps grid of point co. */
static bool mdisp_in_mdispquad(
- BMLoop *l, BMLoop *tl, float p[3], float *x, float *y,
- int res, float axis_x[3], float axis_y[3])
+ BMLoop *l_src, BMLoop *l_dst, const float l_dst_f_center[3],
+ const float p[3], int res,
+ float r_axis_x[3], float r_axis_y[3], float r_uv[2])
{
float v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3];
float eps = FLT_EPSILON * 4000;
- if (is_zero_v3(l->v->no))
- BM_vert_normal_update_all(l->v);
- if (is_zero_v3(tl->v->no))
- BM_vert_normal_update_all(tl->v);
+ if (is_zero_v3(l_src->v->no))
+ BM_vert_normal_update_all(l_src->v);
+ if (is_zero_v3(l_dst->v->no))
+ BM_vert_normal_update_all(l_dst->v);
- compute_mdisp_quad(tl, v1, v2, v3, v4, e1, e2);
+ compute_mdisp_quad(l_dst, l_dst_f_center, v1, v2, v3, v4, e1, e2);
/* expand quad a bit */
cent_quad_v3(c, v1, v2, v3, v4);
@@ -385,13 +348,12 @@ static bool mdisp_in_mdispquad(
add_v3_v3(v1, c); add_v3_v3(v2, c);
add_v3_v3(v3, c); add_v3_v3(v4, c);
- if (!quad_co(x, y, v1, v2, v3, v4, p, l->v->no))
+ if (!quad_co(v1, v2, v3, v4, p, l_src->v->no, r_uv))
return 0;
- *x *= res - 1;
- *y *= res - 1;
+ mul_v2_fl(r_uv, (float)(res - 1));
- mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
+ mdisp_axis_from_quad(v1, v2, v3, v4, r_axis_x, r_axis_y);
return 1;
}
@@ -439,23 +401,21 @@ static void bm_loop_flip_disp(
disp[1] = (mat[0][0] * b[1] - b[0] * mat[1][0]) / d;
}
-static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *l_dst, const BMFace *f_src)
+void BM_loop_interp_multires_ex(
+ BMesh *UNUSED(bm), BMLoop *l_dst, const BMFace *f_src,
+ const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset)
{
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
MDisps *md_dst;
float d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3];
int ix, res;
float axis_x[3], axis_y[3];
-
- if (cd_loop_mdisp_offset == -1)
- return;
/* ignore 2-edged faces */
if (UNLIKELY(l_dst->f->len < 3))
return;
md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset);
- compute_mdisp_quad(l_dst, v1, v2, v3, v4, e1, e2);
+ compute_mdisp_quad(l_dst, f_dst_center, v1, v2, v3, v4, e1, e2);
/* if no disps data allocate a new grid, the size of the first grid in f_src. */
if (!md_dst->totdisp) {
@@ -484,29 +444,20 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *l_dst, const BMFace *f_src)
BMLoop *l_first;
float co1[3], co2[3], co[3];
- copy_v3_v3(co1, e1);
-
- mul_v3_fl(co1, y);
- add_v3_v3(co1, v1);
-
- copy_v3_v3(co2, e2);
- mul_v3_fl(co2, y);
- add_v3_v3(co2, v4);
-
- sub_v3_v3v3(co, co2, co1);
- mul_v3_fl(co, x);
- add_v3_v3(co, co1);
+ madd_v3_v3v3fl(co1, v1, e1, y);
+ madd_v3_v3v3fl(co2, v4, e2, y);
+ interp_v3_v3v3(co, co1, co2, x);
l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
do {
- float x2, y2;
MDisps *md_src;
float src_axis_x[3], src_axis_y[3];
+ float uv[2];
md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
- if (mdisp_in_mdispquad(l_dst, l_iter, co, &x2, &y2, res, src_axis_x, src_axis_y)) {
- old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, (float)x2, (float)y2);
+ if (mdisp_in_mdispquad(l_dst, l_iter, f_src_center, co, res, src_axis_x, src_axis_y, uv)) {
+ old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, uv[0], uv[1]);
bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md_dst->disps[iy * res + ix]);
break;
@@ -517,6 +468,52 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *l_dst, const BMFace *f_src)
}
/**
+ * project the multires grid in target onto f_src's set of multires grids
+ */
+void BM_loop_interp_multires(BMesh *bm, BMLoop *l_dst, const BMFace *f_src)
+{
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+
+ if (cd_loop_mdisp_offset != -1) {
+ float f_dst_center[3];
+ float f_src_center[3];
+
+ BM_face_calc_center_mean(l_dst->f, f_dst_center);
+ BM_face_calc_center_mean(f_src, f_src_center);
+
+ BM_loop_interp_multires_ex(bm, l_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset);
+ }
+}
+
+void BM_face_interp_multires_ex(
+ BMesh *bm, BMFace *f_dst, const BMFace *f_src,
+ const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset)
+{
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst);
+ do {
+ BM_loop_interp_multires_ex(
+ bm, l_iter, f_src,
+ f_dst_center, f_src_center, cd_loop_mdisp_offset);
+ } while ((l_iter = l_iter->next) != l_first);
+}
+
+void BM_face_interp_multires(BMesh *bm, BMFace *f_dst, const BMFace *f_src)
+{
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+
+ if (cd_loop_mdisp_offset != -1) {
+ float f_dst_center[3];
+ float f_src_center[3];
+
+ BM_face_calc_center_mean(f_dst, f_dst_center);
+ BM_face_calc_center_mean(f_src, f_src_center);
+
+ BM_face_interp_multires_ex(bm, f_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset);
+ }
+}
+
+/**
* smooths boundaries between multires grids,
* including some borders in adjacent faces
*/
@@ -623,14 +620,6 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
}
/**
- * project the multires grid in target onto f_src's set of multires grids
- */
-void BM_loop_interp_multires(BMesh *bm, BMLoop *l_dst, const BMFace *f_src)
-{
- bm_loop_interp_mdisps(bm, l_dst, f_src);
-}
-
-/**
* projects a single loop, target, onto f_src for customdata interpolation. multires is handled.
* if do_vertex is true, target's vert data will also get interpolated.
*/
@@ -661,7 +650,7 @@ void BM_loop_interp_from_face(
if (do_vertex) {
vblocks[i] = l_iter->v->head.data;
}
- } while (i++, (l_iter = l_iter->next) != l_first);
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
mul_v2_m3v3(co, axis_mat, l_dst->v->co);
@@ -673,7 +662,7 @@ void BM_loop_interp_from_face(
}
if (do_multires) {
- bm_loop_interp_mdisps(bm, l_dst, f_src);
+ BM_loop_interp_multires(bm, l_dst, f_src);
}
}
@@ -698,7 +687,7 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src)
do {
mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
blocks[i] = l_iter->v->head.data;
- } while (i++, (l_iter = l_iter->next) != l_first);
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
mul_v2_m3v3(co, axis_mat, v_dst->co);