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:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-01-02 20:38:22 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2011-01-02 20:38:22 +0300
commit78162fa7936761ef0aafbc641f1a1b0d9a3fb1ec (patch)
tree0ad5774da06f36b2214d8368cf5172df57ec7665
parent24e80665d8272198783cd6a634cb47a7d289fb1c (diff)
Splitting quad into triangles and merging triangles into quad should
work correct with sculpting data now. Joining two triangles could give incorrect sculpting result for special topologies, but it's that case that can't be nicely handled with our layers architecture.
-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;
+ }
+}