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_multires.h1
-rw-r--r--source/blender/blenkernel/intern/customdata.c47
-rw-r--r--source/blender/blenkernel/intern/multires.c44
3 files changed, 88 insertions, 4 deletions
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index b8131d69dfd..5bdea166cce 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -87,6 +87,7 @@ void mdisp_rot_crn_to_face(int S, int corners, int face_side, float x, float y,
int mdisp_rot_face_to_crn(int corners, int face_side, float u, float v, float *x, float *y);
void mdisp_apply_weight(int S, int corners, int x, int y, int face_side, float crn_weight[4][2], float *u_r, float *v_r);
void mdisp_flip_disp(int S, int corners, float axis_x[2], float axis_y[2], float disp[3]);
+void mdisp_join_tris(struct MDisps *dst, struct MDisps *tri1, struct MDisps *tri2);
#endif
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 2d4e65f8f94..f7606a344c9 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -441,16 +441,55 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
int i, x, y;
int side, S, dst_corners, src_corners;
float crn_weight[4][2];
- float (*sw)[4] = NULL;
+ float (*sw)[4] = (void*)sub_weights;
float (*disps)[3], (*out)[3];
s = sources[0];
dst_corners = multires_mdisp_corners(d);
src_corners = multires_mdisp_corners(s);
- /* XXX: For now, some restrictions on the input
- should be implemented to allow quad<->tris face conversion */
- if(count != 1 || !sub_weights || dst_corners != src_corners) {
+ if(sub_weights && count == 2 && src_corners == 3) {
+ src_corners = multires_mdisp_corners(sources[1]);
+
+ /* special case -- converting two triangles to quad */
+ if(src_corners == 3 && dst_corners == 4) {
+ MDisps tris[2];
+ int vindex[4] = {0};
+
+ S = 0;
+ for(i = 0; i < 2; i++)
+ for(y = 0; y < 4; y++)
+ for(x = 0; x < 4; x++)
+ if(sw[x+i*4][y])
+ vindex[x] = y;
+
+ for(i = 0; i < 2; i++) {
+ float sw[4][4] = {{0}};
+ int a = 7 & ~(1 << vindex[i*2] | 1 << vindex[i*2+1]);
+
+ sw[0][vindex[i*2+1]] = 1;
+ sw[1][vindex[i*2]] = 1;
+
+ for(x = 0; x < 3; x++)
+ if(a & (1 << x))
+ sw[2][x] = 1;
+
+ tris[i] = *((MDisps*)sources[i]);
+ tris[i].disps = MEM_dupallocN(tris[i].disps);
+ layerInterp_mdisps(&sources[i], NULL, (float*)sw, 1, &tris[i]);
+ }
+
+ mdisp_join_tris(d, &tris[0], &tris[1]);
+
+ for(i = 0; i < 2; i++)
+ MEM_freeN(tris[i].disps);
+
+ return;
+ }
+ }
+
+ /* For now, some restrictions on the input */
+ if(count != 1 || !sub_weights) {
for(i = 0; i < d->totdisp; ++i)
zero_v3(d->disps[i]);
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 68ee0d0d0cd..84350127968 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -1981,3 +1981,47 @@ void mdisp_flip_disp(int S, int corners, float axis_x[2], float axis_y[2], float
disp[1] = 0;
}
}
+
+/* Join two triangular displacements into one quad
+ Corners mapping:
+ 2 -------- 3
+ | \ tri2 |
+ | \ |
+ | tri1 \ |
+ 0 -------- 1 */
+void mdisp_join_tris(MDisps *dst, MDisps *tri1, MDisps *tri2)
+{
+ int side, st;
+ int S, x, y, crn;
+ float face_u, face_v, crn_u, crn_v;
+ float (*out)[3];
+ MDisps *src;
+
+ if(dst->disps)
+ MEM_freeN(dst->disps);
+
+ side = sqrt(tri1->totdisp / 3);
+ st = (side<<1)-1;
+
+ dst->totdisp = 4 * side * side;
+ out = dst->disps = MEM_callocN(3*dst->totdisp*sizeof(float), "join disps");
+
+ for(S = 0; S < 4; S++)
+ for(y = 0; y < side; ++y)
+ for(x = 0; x < side; ++x, ++out) {
+ mdisp_rot_crn_to_face(S, 4, st, x, y, &face_u, &face_v);
+ face_u = st - 1 - face_u;
+
+ if(face_v > face_u) {
+ src = tri2;
+ face_u = st - 1 - face_u;
+ face_v = st - 1 - face_v;
+ } else src = tri1;
+
+ crn = mdisp_rot_face_to_crn(3, st, face_u, face_v, &crn_u, &crn_v);
+
+ old_mdisps_bilinear((*out), &src->disps[crn*side*side], side, crn_u, crn_v);
+ (*out)[0] = 0;
+ (*out)[1] = 0;
+ }
+}