Multires math function used for layer interpolation moved from customdata.c to multires.c
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 2 Jan 2011 16:43:28 +0000 (16:43 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 2 Jan 2011 16:43:28 +0000 (16:43 +0000)
No functional changes

source/blender/blenkernel/BKE_multires.h
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/multires.c

index 8fb80292ffb3fc243a4cdc3eb623fa80bc6d8311..b8131d69dfdb3e95b3bfb02f174aeff833e2dfb5 100644 (file)
@@ -81,5 +81,12 @@ void multires_mdisp_smooth_bounds(struct MDisps *disps);
 /* update multires data after topology changing */
 void multires_topology_changed(struct Object *ob);
 
+/**** interpolation stuff ****/
+void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v);
+void mdisp_rot_crn_to_face(int S, int corners, int face_side, float x, float y, float *u, float *v);
+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]);
+
 #endif
 
index 03d3154921409e6eefd747047cb5ac16398d0786..ee3477585f8c22002233a143ad5bccd82cd8c2da 100644 (file)
@@ -396,52 +396,6 @@ static void layerDefault_origspace_face(void *data, int count)
                osf[i] = default_osf;
 }
 
-/* Adapted from sculptmode.c */
-static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
-{
-       int x, y, x2, y2;
-       const int st_max = st - 1;
-       float urat, vrat, uopp;
-       float d[4][3], d2[2][3];
-
-       if(u < 0)
-               u = 0;
-       else if(u >= st)
-               u = st_max;
-       if(v < 0)
-               v = 0;
-       else if(v >= st)
-               v = st_max;
-
-       x = floor(u);
-       y = floor(v);
-       x2 = x + 1;
-       y2 = y + 1;
-
-       if(x2 >= st) x2 = st_max;
-       if(y2 >= st) y2 = st_max;
-       
-       urat = u - x;
-       vrat = v - y;
-       uopp = 1 - urat;
-
-       copy_v3_v3(d[0], disps[y * st + x]);
-       copy_v3_v3(d[1], disps[y * st + x2]);
-       copy_v3_v3(d[2], disps[y2 * st + x]);
-       copy_v3_v3(d[3], disps[y2 * st + x2]);
-       mul_v3_fl(d[0], uopp);
-       mul_v3_fl(d[1], urat);
-       mul_v3_fl(d[2], uopp);
-       mul_v3_fl(d[3], urat);
-
-       add_v3_v3v3(d2[0], d[0], d[1]);
-       add_v3_v3v3(d2[1], d[2], d[3]);
-       mul_v3_fl(d2[0], 1 - vrat);
-       mul_v3_fl(d2[1], vrat);
-
-       add_v3_v3v3(out, d2[0], d2[1]);
-}
-
 static void layerSwap_mdisps(void *data, const int *ci)
 {
        MDisps *s = data;
@@ -473,211 +427,6 @@ static void layerSwap_mdisps(void *data, const int *ci)
        }
 }
 
-static void mdisp_get_crn_rect(int face_side, float crn[3][4][2])
-{
-       float offset = face_side*0.5f - 0.5f;
-       float mid[2];
-
-       mid[0] = offset * 4 / 3;
-       mid[1] = offset * 2 / 3;
-
-       crn[0][0][0] = mid[0]; crn[0][0][1] = mid[1];
-       crn[0][1][0] = offset; crn[0][1][1] = 0;
-       crn[0][2][0] = 0; crn[0][2][1] = 0;
-       crn[0][3][0] = offset; crn[0][3][1] = offset;
-
-       crn[1][0][0] = mid[0]; crn[1][0][1] = mid[1];
-       crn[1][1][0] = offset * 2; crn[1][1][1] = offset;
-       crn[1][2][0] = offset * 2; crn[1][2][1] = 0;
-       crn[1][3][0] = offset; crn[1][3][1] = 0;
-
-       crn[2][0][0] = mid[0]; crn[2][0][1] = mid[1];
-       crn[2][1][0] = offset; crn[2][1][1] = offset;
-       crn[2][2][0] = offset * 2; crn[2][2][1] = offset * 2;
-       crn[2][3][0] = offset * 2; crn[2][3][1] = offset;
-}
-
-static void mdisp_rot_crn_to_face(int S, int corners, int face_side, float x, float y, float *u, float *v)
-{
-       float offset = face_side*0.5f - 0.5f;
-
-       if(corners == 4) {
-               if(S == 1) { *u= offset + x; *v = offset - y; }
-               if(S == 2) { *u= offset + y; *v = offset + x; }
-               if(S == 3) { *u= offset - x; *v = offset + y; }
-               if(S == 0) { *u= offset - y; *v = offset - x; }
-       } else {
-               float crn[3][4][2], vec[4][2];
-               float p[2];
-
-               mdisp_get_crn_rect(face_side, crn);
-
-               interp_v2_v2v2(vec[0], crn[S][0], crn[S][1], x / offset);
-               interp_v2_v2v2(vec[1], crn[S][3], crn[S][2], x / offset);
-               interp_v2_v2v2(vec[2], crn[S][0], crn[S][3], y / offset);
-               interp_v2_v2v2(vec[3], crn[S][1], crn[S][2], y / offset);
-
-               isect_seg_seg_v2_point(vec[0], vec[1], vec[2], vec[3], p);
-
-               (*u) = p[0];
-               (*v) = p[1];
-       }
-}
-
-static int mdisp_pt_in_crn(float p[2], float crn[4][2])
-{
-       float v[2][2];
-       float a[2][2];
-
-       sub_v2_v2v2(v[0], crn[1], crn[0]);
-       sub_v2_v2v2(v[1], crn[3], crn[0]);
-
-       sub_v2_v2v2(a[0], p, crn[0]);
-       sub_v2_v2v2(a[1], crn[2], crn[0]);
-
-       if(cross_v2v2(a[0], v[0]) * cross_v2v2(a[1], v[0]) < 0)
-               return 0;
-
-       if(cross_v2v2(a[0], v[1]) * cross_v2v2(a[1], v[1]) < 0)
-               return 0;
-
-       return 1;
-}
-
-static void face_to_crn_interp(float u, float v, float v1[2], float v2[2], float v3[2], float v4[2], float *x)
-{
-       float a = (v4[1]-v3[1])*v2[0]+(-v4[1]+v3[1])*v1[0]+(-v2[1]+v1[1])*v4[0]+(v2[1]-v1[1])*v3[0];
-       float b = (v3[1]-v)*v2[0]+(v4[1]-2*v3[1]+v)*v1[0]+(-v4[1]+v3[1]+v2[1]-v1[1])*u+(v4[0]-v3[0])*v-v1[1]*v4[0]+(-v2[1]+2*v1[1])*v3[0];
-       float c = (v3[1]-v)*v1[0]+(-v3[1]+v1[1])*u+v3[0]*v-v1[1]*v3[0];
-       float d = b * b - 4 * a * c;
-       float x1, x2;
-
-       if(a == 0) {
-               *x = -c / b;
-               return;
-       }
-
-       x1 = (-b - sqrtf(d)) / (2 * a);
-       x2 = (-b + sqrtf(d)) / (2 * a);
-
-       *x = maxf(x1, x2);
-}
-
-static int mdisp_rot_face_to_crn(int corners, int face_side, float u, float v, float *x, float *y)
-{
-       float offset = face_side*0.5f - 0.5f;
-       int S;
-
-       if (corners == 4) {
-               if(u <= offset && v <= offset) S = 0;
-               else if(u > offset  && v <= offset) S = 1;
-               else if(u > offset  && v > offset) S = 2;
-               else if(u <= offset && v >= offset)  S = 3;
-
-               if(S == 0) {
-                       *y = offset - u;
-                       *x = offset - v;
-               } else if(S == 1) {
-                       *x = u - offset;
-                       *y = offset - v;
-               } else if(S == 2) {
-                       *y = u - offset;
-                       *x = v - offset;
-               } else if(S == 3) {
-                       *x= offset - u;
-                       *y = v - offset;
-               }
-       } else {
-               float crn[3][4][2];
-               float p[2] = {u, v};
-
-               mdisp_get_crn_rect(face_side, crn);
-
-               for (S = 0; S < 3; ++S) {
-                       if (mdisp_pt_in_crn(p, crn[S]))
-                               break;
-               }
-
-               face_to_crn_interp(u, v, crn[S][0], crn[S][1], crn[S][3], crn[S][2], &p[0]);
-               face_to_crn_interp(u, v, crn[S][0], crn[S][3], crn[S][1], crn[S][2], &p[1]);
-
-               *x = p[0] * offset;
-               *y = p[1] * offset;
-       }
-
-       return S;
-}
-
-static 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)
-{
-       float u = 0.f, v = 0.f, xl, yl;
-       float mid1[2], mid2[2], mid3[2];
-
-       mdisp_rot_crn_to_face(S, corners, face_side, x, y, &u, &v);
-
-       if(corners == 4) {
-               xl = u / (face_side - 1);
-               yl = v / (face_side - 1);
-
-               mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
-               mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
-               mid2[0] = crn_weight[3][0] * (1 - xl) + crn_weight[2][0] * xl;
-               mid2[1] = crn_weight[3][1] * (1 - xl) + crn_weight[2][1] * xl;
-               mid3[0] = mid1[0] * (1 - yl) + mid2[0] * yl;
-               mid3[1] = mid1[1] * (1 - yl) + mid2[1] * yl;
-       } else {
-               yl = v / (face_side - 1);
-
-               if(v == face_side - 1) xl = 1;
-               else xl = 1 - (face_side - 1 - u) / (face_side - 1 - v);
-
-               mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
-               mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
-               mid3[0] = mid1[0] * (1 - yl) + crn_weight[2][0] * yl;
-               mid3[1] = mid1[1] * (1 - yl) + crn_weight[2][1] * yl;
-       }
-
-       *u_r = mid3[0];
-       *v_r = mid3[1];
-}
-
-static void mdisp_flip_disp(int S, int corners, float axis_x[2], float axis_y[2], float disp[3])
-{
-       float crn_x[2], crn_y[2];
-       float vx[2], vy[2], coord[2];
-
-       if (corners == 4) {
-               float x[4][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
-               float y[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
-
-               copy_v2_v2(crn_x, x[S]);
-               copy_v2_v2(crn_y, y[S]);
-
-               mul_v2_v2fl(vx, crn_x, disp[0]);
-               mul_v2_v2fl(vy, crn_y, disp[1]);
-               add_v2_v2v2(coord, vx, vy);
-
-               project_v2_v2v2(vx, coord, axis_x);
-               project_v2_v2v2(vy, coord, axis_y);
-
-               disp[0] = len_v2(vx);
-               disp[1] = len_v2(vy);
-
-               if(dot_v2v2(vx, axis_x) < 0)
-                       disp[0] = -disp[0];
-
-               if(dot_v2v2(vy, axis_y) < 0)
-                       disp[1] = -disp[1];
-       } else {
-               /* XXX: it was very overhead code to support displacement flipping
-                       for case of tris without visible profit.
-                       Maybe its not really big limitation? for now? (nazgul) */
-               disp[0] = 0;
-               disp[1] = 0;
-       }
-}
-
 static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                                float *sub_weights, int count, void *dest)
 {
@@ -739,7 +488,7 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                                mdisp_apply_weight(S, dst_corners, x, y, st, crn_weight, &face_u, &face_v);
                                crn = mdisp_rot_face_to_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
 
-                               mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
+                               old_mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
                                mdisp_flip_disp(crn, dst_corners, axis_x, axis_y, *out);
                        }
                }
index 2224b3d8d496d0918cadb850aea4eb1e41406600..68ee0d0d0cd591230e70d4e0be17cab7fe2fbca2 100644 (file)
@@ -837,7 +837,7 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int loca
 ***************************/
 
 /* Adapted from sculptmode.c */
-static void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
+void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
 {
        int x, y, x2, y2;
        const int st_max = st - 1;
@@ -1774,3 +1774,210 @@ void multires_mdisp_smooth_bounds(MDisps *disps)
                }
        }
 }
+
+/***************** Multires interpolation stuff *****************/
+
+static void mdisp_get_crn_rect(int face_side, float crn[3][4][2])
+{
+       float offset = face_side*0.5f - 0.5f;
+       float mid[2];
+
+       mid[0] = offset * 4 / 3;
+       mid[1] = offset * 2 / 3;
+
+       crn[0][0][0] = mid[0]; crn[0][0][1] = mid[1];
+       crn[0][1][0] = offset; crn[0][1][1] = 0;
+       crn[0][2][0] = 0; crn[0][2][1] = 0;
+       crn[0][3][0] = offset; crn[0][3][1] = offset;
+
+       crn[1][0][0] = mid[0]; crn[1][0][1] = mid[1];
+       crn[1][1][0] = offset * 2; crn[1][1][1] = offset;
+       crn[1][2][0] = offset * 2; crn[1][2][1] = 0;
+       crn[1][3][0] = offset; crn[1][3][1] = 0;
+
+       crn[2][0][0] = mid[0]; crn[2][0][1] = mid[1];
+       crn[2][1][0] = offset; crn[2][1][1] = offset;
+       crn[2][2][0] = offset * 2; crn[2][2][1] = offset * 2;
+       crn[2][3][0] = offset * 2; crn[2][3][1] = offset;
+}
+
+static int mdisp_pt_in_crn(float p[2], float crn[4][2])
+{
+       float v[2][2];
+       float a[2][2];
+
+       sub_v2_v2v2(v[0], crn[1], crn[0]);
+       sub_v2_v2v2(v[1], crn[3], crn[0]);
+
+       sub_v2_v2v2(a[0], p, crn[0]);
+       sub_v2_v2v2(a[1], crn[2], crn[0]);
+
+       if(cross_v2v2(a[0], v[0]) * cross_v2v2(a[1], v[0]) < 0)
+               return 0;
+
+       if(cross_v2v2(a[0], v[1]) * cross_v2v2(a[1], v[1]) < 0)
+               return 0;
+
+       return 1;
+}
+
+static void face_to_crn_interp(float u, float v, float v1[2], float v2[2], float v3[2], float v4[2], float *x)
+{
+       float a = (v4[1]-v3[1])*v2[0]+(-v4[1]+v3[1])*v1[0]+(-v2[1]+v1[1])*v4[0]+(v2[1]-v1[1])*v3[0];
+       float b = (v3[1]-v)*v2[0]+(v4[1]-2*v3[1]+v)*v1[0]+(-v4[1]+v3[1]+v2[1]-v1[1])*u+(v4[0]-v3[0])*v-v1[1]*v4[0]+(-v2[1]+2*v1[1])*v3[0];
+       float c = (v3[1]-v)*v1[0]+(-v3[1]+v1[1])*u+v3[0]*v-v1[1]*v3[0];
+       float d = b * b - 4 * a * c;
+       float x1, x2;
+
+       if(a == 0) {
+               *x = -c / b;
+               return;
+       }
+
+       x1 = (-b - sqrtf(d)) / (2 * a);
+       x2 = (-b + sqrtf(d)) / (2 * a);
+
+       *x = maxf(x1, x2);
+}
+
+void mdisp_rot_crn_to_face(int S, int corners, int face_side, float x, float y, float *u, float *v)
+{
+       float offset = face_side*0.5f - 0.5f;
+
+       if(corners == 4) {
+               if(S == 1) { *u= offset + x; *v = offset - y; }
+               if(S == 2) { *u= offset + y; *v = offset + x; }
+               if(S == 3) { *u= offset - x; *v = offset + y; }
+               if(S == 0) { *u= offset - y; *v = offset - x; }
+       } else {
+               float crn[3][4][2], vec[4][2];
+               float p[2];
+
+               mdisp_get_crn_rect(face_side, crn);
+
+               interp_v2_v2v2(vec[0], crn[S][0], crn[S][1], x / offset);
+               interp_v2_v2v2(vec[1], crn[S][3], crn[S][2], x / offset);
+               interp_v2_v2v2(vec[2], crn[S][0], crn[S][3], y / offset);
+               interp_v2_v2v2(vec[3], crn[S][1], crn[S][2], y / offset);
+
+               isect_seg_seg_v2_point(vec[0], vec[1], vec[2], vec[3], p);
+
+               (*u) = p[0];
+               (*v) = p[1];
+       }
+}
+
+int mdisp_rot_face_to_crn(int corners, int face_side, float u, float v, float *x, float *y)
+{
+       float offset = face_side*0.5f - 0.5f;
+       int S;
+
+       if (corners == 4) {
+               if(u <= offset && v <= offset) S = 0;
+               else if(u > offset  && v <= offset) S = 1;
+               else if(u > offset  && v > offset) S = 2;
+               else if(u <= offset && v >= offset)  S = 3;
+
+               if(S == 0) {
+                       *y = offset - u;
+                       *x = offset - v;
+               } else if(S == 1) {
+                       *x = u - offset;
+                       *y = offset - v;
+               } else if(S == 2) {
+                       *y = u - offset;
+                       *x = v - offset;
+               } else if(S == 3) {
+                       *x= offset - u;
+                       *y = v - offset;
+               }
+       } else {
+               float crn[3][4][2];
+               float p[2] = {u, v};
+
+               mdisp_get_crn_rect(face_side, crn);
+
+               for (S = 0; S < 3; ++S) {
+                       if (mdisp_pt_in_crn(p, crn[S]))
+                               break;
+               }
+
+               face_to_crn_interp(u, v, crn[S][0], crn[S][1], crn[S][3], crn[S][2], &p[0]);
+               face_to_crn_interp(u, v, crn[S][0], crn[S][3], crn[S][1], crn[S][2], &p[1]);
+
+               *x = p[0] * offset;
+               *y = p[1] * offset;
+       }
+
+       return S;
+}
+
+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)
+{
+       float u, v, xl, yl;
+       float mid1[2], mid2[2], mid3[2];
+
+       mdisp_rot_crn_to_face(S, corners, face_side, x, y, &u, &v);
+
+       if(corners == 4) {
+               xl = u / (face_side - 1);
+               yl = v / (face_side - 1);
+
+               mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
+               mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
+               mid2[0] = crn_weight[3][0] * (1 - xl) + crn_weight[2][0] * xl;
+               mid2[1] = crn_weight[3][1] * (1 - xl) + crn_weight[2][1] * xl;
+               mid3[0] = mid1[0] * (1 - yl) + mid2[0] * yl;
+               mid3[1] = mid1[1] * (1 - yl) + mid2[1] * yl;
+       } else {
+               yl = v / (face_side - 1);
+
+               if(v == face_side - 1) xl = 1;
+               else xl = 1 - (face_side - 1 - u) / (face_side - 1 - v);
+
+               mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
+               mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
+               mid3[0] = mid1[0] * (1 - yl) + crn_weight[2][0] * yl;
+               mid3[1] = mid1[1] * (1 - yl) + crn_weight[2][1] * yl;
+       }
+
+       *u_r = mid3[0];
+       *v_r = mid3[1];
+}
+
+void mdisp_flip_disp(int S, int corners, float axis_x[2], float axis_y[2], float disp[3])
+{
+       float crn_x[2], crn_y[2];
+       float vx[2], vy[2], coord[2];
+
+       if (corners == 4) {
+               float x[4][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
+               float y[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
+
+               copy_v2_v2(crn_x, x[S]);
+               copy_v2_v2(crn_y, y[S]);
+
+               mul_v2_v2fl(vx, crn_x, disp[0]);
+               mul_v2_v2fl(vy, crn_y, disp[1]);
+               add_v2_v2v2(coord, vx, vy);
+
+               project_v2_v2v2(vx, coord, axis_x);
+               project_v2_v2v2(vy, coord, axis_y);
+
+               disp[0] = len_v2(vx);
+               disp[1] = len_v2(vy);
+
+               if(dot_v2v2(vx, axis_x) < 0)
+                       disp[0] = -disp[0];
+
+               if(dot_v2v2(vy, axis_y) < 0)
+                       disp[1] = -disp[1];
+       } else {
+               /* XXX: it was very overhead code to support displacement flipping
+                       for case of tris without visible profit.
+                       Maybe its not really big limitation? for now? (nazgul) */
+               disp[0] = 0;
+               disp[1] = 0;
+       }
+}