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 /source/blender/blenkernel/intern
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.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/customdata.c47
-rw-r--r--source/blender/blenkernel/intern/multires.c44
2 files changed, 87 insertions, 4 deletions
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;
+ }
+}